//
//  main.swift
//  SwiftTest
//
//  Created by cygarm on 15/6/12.
//  Copyright (c) 2015年 cygarm. All rights reserved.
//

import Foundation

println("Hello, World!")

// MARK: 可选类型
/*
使用可选类型（optionals）来处理值可能缺失的情况。

Swift定义后缀 ?  来作为标准库中的定义的命名型类型 Optional<T>  的简写。
换句话说，下面两个声明是等价的：
var optionalInteger: Int?
var optionalInteger: Optional<Int>
*/
////{
// 	var serverResponseCode: Int? = 404
// 	// serverResponseCode 包含一个可选的 Int 值 404
// 	serverResponseCode = nil
// 	// serverResponseCode 现在不包含值

// 	var surveyAnswer: String?
// 	// surveyAnswer 被自动设置为 nil
////}

// MARK: -- 强制解析
/*
当你确定可选类型确实包含值之后，你可以在可选的名字后面加一个感叹号（ !  ）来获取值。
*/

// MARK: -- 隐式解析可选类型
/*
有时候在程序架构中，第一次被赋值之后，可以确定一个可选类型总会有值。
在这种情况下，每次都要判断和解析可选值是非常低效的，因为可以确定它总会有值。
这种类型的可选状态被定义为隐式解析可选类型（implicitly unwrapped optionals）。
把想要用作可选的类型的后面的问号（ String?  ）改成感叹号（ String!  ）来声明一个隐式解析可选类型

如果你在隐式解析可选类型没有值的时候尝试取值，会触发运行时错误。
和你在没有值的普通可选类型后面加一个惊叹号一样。

如果一个变量之后可能变成 nil  的话请不要使用隐式解析可选类型。
如果你需要在变量的生命周期中判断是否是 nil  的话，请使用普通可选类型。

Swift语言定义后缀 !  作为标准库中命名类型 ImplicitlyUnwrappedOptional<T>  的简写。
换句话说，下面两个声明等价：
var implicitlyUnwrappedString: String!
var implicitlyUnwrappedString: ImplicitlyUnwrappedOptional<String>
*/
////{
// 	let possibleString: String? = "An optional string."
// 	println(possibleString!) // 需要惊叹号来获取值
// 	// 输出 "An optional string."

// 	let assumedString: String! = "An implicitly unwrapped optional string."
// 	println(assumedString) // 不需要感叹号
// 	// 输出 "An implicitly unwrapped optional string."

// 	if assumedString {
// 		println(assumedString)
// 	}
// 	// 输出 "An implicitly unwrapped optional string."

// 	if let definiteString = assumedString {
// 		println(definiteString)
// 	}
// 	// 输出 "An implicitly unwrapped optional string."
////}



// MARK: 断言
////{
// 	let age = -3
// 	assert(age >= 0, "A person's age cannot be less than zero")
// 	// 因为 age < 0，所以断言会触发

// 	assert(age >= 0)
////}



//MARK: 集合类型 Collection Type
//MARK: -- 数组 Arrays
/*
Swift语言使用类型名紧接中括号 []  来简化标准库中定义的命名型类型 Array<T>  。
换句话说，下面两个声明是等价的：
let someArray: String[] = ["Alex", "Brian", "Dave"]
let someArray: Array<String> = ["Alex", "Brian", "Dave"]
*/
// //{
// var someInts = [Int]()
// println("someInts is of type [Int] with \(someInts.count) items.")

// someInts.append(3)
// for x in someInts {
//    println("item \(x)")
// }
// //}


//MARK: -- 集合 Sets
////{
//    var letters = Set<Character>()
//    letters.insert("a")
//
//    if letters.isEmpty {
//        println("letter empty")
//    } else {
//        println("letters=\(letters)")
//    }
//    if letters.contains("a") {
//        println("have item:a")
//    } else {
//        println("no item:a")
//    }
////}


//MARK: -- 字典 Dictionaries


//MARK: 控制流
//MARK: -- For

//MARK: -- While

//MARK: -- 条件语句

//MARK: -- 控制转移语句 Control Transfer Statements
////{
//    var loopCnt = 3
//    testOfLoop: while loopCnt-- != 0 {
//        println("step 1")
//        continue testOfLoop
//        println("step 2")
//    }
////}



//MARK: 函数 Functions
//MARK: -- 参数命名
////{
//    func sayHello(#personName: String, gender: String = "Male") -> String {
//        let greeting = "Hello, " + personName + "(" + gender + ")" + "!"
//        return greeting
//    }
//
//    println(sayHello(personName: "Bob", gender: "Female"))
////}

////MARK: -- 输入输出参数
////{
//    func swapTwoInts(inout a: Int, inout b: Int) {
//        let tmp = a
//        a = b
//        b = tmp
//    }
//
//    var someInt = 3
//    var anotherInt = 107
//    swapTwoInts(&someInt, &anotherInt)
//    println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
////}

//MARK: -- 函数类型作为返回类型
////{
//    func stepForward(input: Int) ->Int {
//        return input + 1
//    }
//
//    func stepBackward(input: Int) ->Int {
//        return input - 1
//    }
//
//    func chooseStepFunction(backwards: Bool) ->(Int) ->Int {
//        return backwards ? stepBackward : stepForward
//    }
//
//    var currentValue = 3
//    let moveNearerToZero = chooseStepFunction(currentValue > 0)
//
//    println("Counting to Zero:")
//    while currentValue != 0 {
//        println("\(currentValue)...")
//        currentValue = moveNearerToZero(currentValue)
//    }
//    println("Zero!")
////}

//MARK: -- 嵌套函数
////{
//    func chooseStepFunction2(backwards: Bool) ->(Int) ->Int {
//        func stepForward (input: Int) -> Int {return input + 1}
//        func stepBackward(input: Int) -> Int {return input - 1}
//        return backwards ? stepBackward : stepForward
//    }
//
//    var currentValue2 = -4
//    let moveNearerToZero2 = chooseStepFunction2(currentValue2 > 0)
//
//    println("Counting to Zero:")
//    while currentValue2 != 0 {
//        println("\(currentValue2)...")
//        currentValue2 = moveNearerToZero2(currentValue2)
//    }
//    println("Zero!")
////}

//MARK: -- 柯里化函数  curried function
/*
柯里化函数（curried function）的类型相当于一个嵌套函数类型。
*/
////{
//func addTwoNumbers(a: Int)(b: Int) -> Int{
//	return a + b
//}
//addTwoNumbers(4)(b: 5) // returns 9
///*
//柯里化函数的函数类型从右向左组成一组。
//例如，函数类型 Int -> Int -> Int  可以被理解为 Int -> (Int -> Int)
//也就是说，一个函数传入一个 Int  然后输出作为另一个函数的输入，然后又返回一个 Int  。
//
//可以使用如下嵌套函数来重写柯里化函数 addTwoNumbers()() :
//*/
//func addTwoNumbers(a: Int) -> (Int -> Int){
//	func addTheSecondNumber(b: Int) -> Int{
//		return a + b
//	}
//	return addTheSecondNumber
//}
//addTwoNumbers(4)(5) // Returns 9
////}



//MARK: 闭包 Closures
/*
内联闭包表达式语法
{ (parameters) -> returnType in
statements
}
*/
////{
//let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
//var reserved = [String]()
//
//// MARK: -- 闭包完整参数类型格式
//reserved = sorted(names, {(s1: String, s2: String) -> Bool in return s1 > s2})
//println("\(reserved)")
//
//// MARK: -- 作为函数参数,自动推断参数及返回值类型
//reserved = sorted(names, {s1, s2 in return s1 > s2})
//println("\(reserved)")
//
//// MARK: -- 单表达式闭包隐式返回
//reserved = sorted(names, {s1, s2 in s1 > s2})
//println("\(reserved)")
//
//// MARK: -- 参数名称缩写
//reserved = sorted(names, {$0 > $1})
//println("\(reserved)")
//
//// MARK: -- 运算符函数
//reserved = sorted(names, >)
//println("\(reserved)")
////}

// MARK: -- 尾随闭包
// MARK: ---- e.g.1
//reserved = sorted(names){$0 > $1}

// MARK: ---- e.g.2
////{
//    let digitNames = [
//        0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
//        5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
//    ]
//    let numbers = [16, 58, 510]
//
//    let strings = numbers.map {
//        (var number) -> String in
//        var output = ""
//        while number > 0 {
//            output = digitNames[number % 10]! + output
//            number /= 10
//        }
//        return output
//    }
//    println("strings=\(strings)")
////}


//MARK: -- 捕获值
////{
//    func makeIncrementor(forIncrement amount: Int) -> () ->Int {
//        var runningTotal = 0
//        func incrementor() -> Int {
//            runningTotal += amount
//            println("runningTotal=\(runningTotal)")
//            return runningTotal
//        }
//        return incrementor
//    }
//
//    let incrementByTen = makeIncrementor(forIncrement: 10)
//
//    incrementByTen()
//    incrementByTen()
//
//    let incrementBySeven = makeIncrementor(forIncrement: 7)
//    incrementBySeven()
////}

// MARK: -- 自动闭包函数 @autoclosure属性
/*
你可以对函数类型应用带有参数类型 ()  并返回表达式类型的 @autoclosure  属性（见类型属性章节）。
一个自动闭包函数捕获特定表达式上的隐式闭包而非表达式本身。
*/
////{
//func simpleAssert(@autoclosure condition:  () -> Bool, message: String){
//	if !condition(){
//		println(message)
//	}
//}
//let testNumber = 5
//simpleAssert(testNumber % 2 == 0, "testNumber isn't an even number.")
//// prints "testNumber isn't an even number."
////}



// MARK: 枚举 Enumerations
// MARK: -- 匹配枚举值和Swith语句
////{
//    enum CompassPoint {
//        case North
//        case South
//        case East
//        case West
//    }
//
//    var directionToHead = CompassPoint.South
//    switch directionToHead {
//        case .North:
//            println(".North")
//        case .South:
//            println(".South")
//        case .East:
//            println(".East")
//        case .West:
//            println(".West")
//    }
////}

//// MARK: -- 相关值 Associated Values
// //{
// enum BarCode {
//    case UPCA(Int, Int, Int)
//    case QRCode(String)
// }
// var productBarcode = BarCode.UPCA(8, 85909_51226, 3)
// // MARK: ---- 只能一个有效值
// productBarcode = BarCode.QRCode("ABCDEFGHIJKLMNOP")//QRCode会使.UPCA失效

// switch productBarcode {
// case .UPCA(let numberSystem, let identifier, let check):
//    println("UPC-A with value of \(numberSystem), \(identifier), \(check)")
// case .QRCode(let productcode):
//    println("QR code with value of \(productcode)")
// }

// // MARK: ---- 提取值类型简化写法
// switch productBarcode {
// case let .UPCA(numberSystem, identifier, check):
//    println("UPC-A with value of \(numberSystem), \(identifier), \(check)")
// case let .QRCode(productcode):
//    println("QR code with value of \(productcode)")
// }
// //}

// MARK: -- 原始值 Raw Values
////{
//    enum Planet: Int {
//        case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
//    }
//    let earthsOrder = Planet.Earth.rawValue
//    println("earthsOrder=\(earthsOrder)")
//
//    let possiblePlanet = Planet(rawValue: 7)
//    println("possiblePlanet=\(possiblePlanet)")
////}



// MARK: 类和结构体
// //{
// /*
// 类&结构体 共同点:
// * 定义属性用于存储值
// * 定义方法用于提供功能
// * 定义附属脚本用于访问值
// * 定义构造器用于生成初始化值
// * 通过扩展以增加默认实现的功能
// * 符合协议以对某类提供标准功能

// 类 附加功能:
// * 继承允许一个类继承另一个类的特征
// * 类型转换允许在运行时检查和解释一个类实例的类型
// * 解构器允许一个类实例释放任何其所被分配的资源
// * 引用计数允许对一个类的多次引用

// 注意:
// 结构体总是通过被复制的方式在代码中传递，因此请不要使用引用计数
// */
// struct Resolution {
//    var width = 0
//    var height = 0
// }
// class VideoMode {
//    var resolution = Resolution()
//    var interlaced = false
//    var frameRate = 0.0
//    var name: String?
// }

// let hd = Resolution(width: 1920, height: 1080)
// let tenEighty = VideoMode()
// tenEighty.resolution = hd
// tenEighty.interlaced = true
// tenEighty.name = "1080i"
// tenEighty.frameRate = 25.0

// let alsoTenEighty = tenEighty
// alsoTenEighty.frameRate = 30.0


//// MARK: -- 恒等运算符 ===判断类的实例引用是否指向同一个实例
// /*
// “等价于”表示两个类类型（class type）的常量或者变量引用同一个类实例。
// “等于”表示两个实例的值“相等”或“相同”，判定时要遵照类设计者定义定义的评判标准，
// 因此相比于“相等”，这是一种更加合适的叫法。

// 一个 Swift常量或者变量引用一个引用类型的实例与 C 语言中的指针类似，
// 不同的是并不直接指向内存中的某个地址，
// 而且也不要求你使用星号（*）来表明你在创建一个引用。
// Swift 中这些引用与其它的常量或变量的定义方式相同。
// */
// if tenEighty === alsoTenEighty {
//    println("tenEighty and alsoTenEighty refer to the same Resolution instance.")
// }
// //}

//MARK: -- 类和结构体数据类型的选择
/*
结构体实例总是通过值传递，类实例总是通过引用传递。

按照通用的准则，当符合一条或多条以下条件时，请考虑构建结构体：
* 结构体的主要目的是用来封装少量相关简单数据值。
* 有理由预计一个结构体实例在赋值或传递时，封装的数据将会被拷贝而不是被引用。
* 任何在结构体中储存的值类型属性，也将会被拷贝，而不是被引用。
* 结构体不需要去继承另一个已存在类型的属性或者行为。

合适的结构体候选者包括：
* 几何形状的大小，封装一个 width  属性和 height  属性，两者均为 Double  类型。
* 一定范围内的路径，封装一个 start  属性和 length  属性，两者均为 Int  类型。
* 三维坐标系内一点，封装 x  ， y  和 z  属性，三者均为 Double  类型。

在所有其它案例中，定义一个类，生成一个它的实例，并通过引用来管理和传递。
实际中，这意味着绝大部分的自定义数据构造都应该是类，而非结构体。
*/



// MARK: 属性 Properties
// MARK: -- 存储属性 Stored Properties
// //{
// struct FixedLengthRange {
//    var firstValue: Int
//    let length: Int
// }
// var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// rangeOfThreeItems.firstValue = 6

// // MARK: ---- 常量和存储属性

// 如果创建了一个结构体的实例并赋值给一个常量，则无法修改实例的任何属性，
// 即使定义了变量存储属性

// 这种行为是由于结构体（struct）属于值类型。
// 当值类型的实例被声明为常量的时候，它的所有属性也就成了常量。

// let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// //rangeOfFourItems.firstValue = 6 //报错!!!
// //}

// MARK: ---- 延迟存储属性
////{
//    /*
//    延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。
//    在属性声明前使用 lazy  来标示一个延迟存储属性。
//    延迟属性很有用，当属性的值依赖于在实例的构造过程结束前无法知道具体值的外部因素时，
//    或者当属性的值需要复杂或大量计算时，可以只在需要的时候来计算它。
//
//    必须将延迟存储属性声明成变量（使用 var  关键字），
//    因为属性的值在实例构造完成之前可能无法得到。
//    而常量属性在构造过程完成之前必须要有初始值，因此无法声明成延迟属性。
//    */
//    class DataImporter {
//        /*
//        DataImporter 是一个将外部文件中的数据导入的类。
//        这个类的初始化会消耗不少时间。
//        */
//        var fileName = "data.txt"
//        // 这是提供数据导入功能
//    }
//
//    class DataManager {
//        lazy var importer = DataImporter()
//        var data = [String]()
//        // 这是提供数据管理功能
//    }
//
//    let manager = DataManager()
//    manager.data.append("Some data")
//    manager.data.append("Some more data")
//    // DataImporter 实例的 importer 属性还没有被创建
//
//    /*
//    由于使用了lazy,importer属性只有在第一次被访问的时候才被创建。
//    比如访问它的属性 fileName 时：
//    */
//    println(manager.importer.fileName)
//    // DataImporter 实例的 importer 属性现在被创建了
//    // 输出 "data.txt”
////}

// MARK: ---- 存储属性和实例变量
// MARK: -- 计算属性 Computed Properties
////{
//    struct Point {
//        var x = 0.0, y = 0.0
//    }
//    struct Size {
//        var width = 0.0, height = 0.0
//    }
//    struct Rect {
//        var origin = Point()
//        var size = Size()
//        var center: Point {
//            get {
//                let centerX = origin.x + (size.width / 2)
//                let centerY = origin.y + (size.height / 2)
//                return Point(x: centerX, y: centerY)
//            }
//            set {
//                origin.x = newValue.x - (size.width / 2)
//                origin.y = newValue.y - (size.height / 2)
//            }
//        }
//    }
//    var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
//    let initialSquareCenter = square.center
//    square.center = Point(x: 15.0, y: 15.0)
//    println("square.origin is now at (\(square.origin.x), \(square.origin.y))")
//    // 输出 "square.origin is now at (10.0, 10.0)”
////}

// MARK: ---- 只读计算属性
////{
//    /*
//    必须使用 var  关键字定义计算属性，包括只读计算属性，因为它们的值不是固定的。
//    let  关键字只用来声明常量属性，表示初始化后再也无法修改的值。
//    */
//    struct Cuboid {
//        var width = 0.0, height = 0.0, depth = 0.0
//        var volume: Double {
//            return width * height * depth
//        }
//    }
//    let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
//    println("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
//    // 输出 "the volume of fourByFiveByTwo is 40.0"
////}

// MARK: -- 属性观察器 Property Observers
////{
//    /*
//    属性观察器监控和响应属性值的变化，每次属性被设置值的时候都会调用属性观察器，
//    甚至新的值和现在的值相同的时候也不例外。
//
//    可以为除了延迟存储属性之外的其他存储属性添加属性观察器，
//    也可以通过重载属性的方式为继承的属性（包括存储属性和计算属性）添加属性观察器。
//
//    不需要为无法重载的计算属性添加属性观察器，因为可以通过 setter 直接监控和响应值的变化。
//
//    可以为属性添加如下的一个或全部观察器：
//    * willSet  在设置新的值之前调用
//    * didSet   在新的值被设置之后立即调用
//
//    willSet  和 didSet  观察器在属性初始化过程中不会被调用，
//    它们只会当属性的值在初始化之外的地方被设置时被调用。
//    */
//    class StepCounter {
//        var totalSteps: Int = 0 {
//            willSet(newTotalSteps) {
//                println("About to set totalSteps to \(newTotalSteps)")
//            }
//            didSet {
//                if totalSteps > oldValue {
//                    println("Added \(totalSteps - oldValue) steps")
//                }
//            }
//        }
//    }
//    let stepCounter = StepCounter()
//    stepCounter.totalSteps = 200
//    // About to set totalSteps to 200
//    // Added 200 steps
//    stepCounter.totalSteps = 360
//    // About to set totalSteps to 360
//    // Added 160 steps
//    stepCounter.totalSteps = 896
//    // About to set totalSteps to 896
//    // Added 536 steps
////}

// MARK: -- 类型属性
/*
对于值类型（指结构体和枚举）可以定义存储型和计算型类型属性，
对于类（class）则只能定义计算型类型属性。
值类型的存储型类型属性可以是变量或常量，
计算型类型属性跟实例的计算属性一样定义成变量属性。

跟实例的存储属性不同，必须给存储型类型属性指定默认值，
因为类型本身无法在初始化过程中使用构造器给类型属性赋值。
*/
/*
在 Swift 编程语言中，类型属性是作为类型定义的一部分写在类型最外层的花括号内，
因此它的作用范围也就在类型支持的范围内。

类型属性是通过类型本身来获取和设置，而不是通过实例
*/
// MARK: ---- e.g.1
////{
//    struct SomeStructure {
//        static var storedTypeProperty = "Some value."
//        static var computedTypeProperty: Int {
//            // 这里返回一个 Int 值
//            return 3
//        }
//    }
//    enum SomeEnumeration {
//        static var storedTypeProperty = "Some value."
//        static var computedTypeProperty: Int {
//            // 这里返回一个 Int 值
//            return 4
//        }
//    }
//    class SomeClass {
//        class var computedTypeProperty: Int {
//            // 这里返回一个 Int 值
//            return 5
//        }
//    }
//
//    println(SomeClass.computedTypeProperty)
//    // 输出 "42"
//    println(SomeStructure.storedTypeProperty)
//    // 输出 "Some value."
//    SomeStructure.storedTypeProperty = "Another value."
//    println(SomeStructure.storedTypeProperty)
//    // 输出 "Another value.”
////}

// MARK: ---- e.g.2
////{
//    struct AudioChannel {
//        static let thresholdLevel = 10
//        static var maxInputLevelForAllChannels = 0
//        var currentLevel: Int = 0 {
//            didSet {
//                if currentLevel > AudioChannel.thresholdLevel {
//                    // 将新电平值设置为阀值
//                    currentLevel = AudioChannel.thresholdLevel
//                }
//                if currentLevel > AudioChannel.maxInputLevelForAllChannels {
//                    // 存储当前电平值作为新的最大输入电平
//                    AudioChannel.maxInputLevelForAllChannels = currentLevel
//                }
//            }
//        }
//    }
//    var leftChannel = AudioChannel()
//    var rightChannel = AudioChannel()
//    leftChannel.currentLevel = 7
//    println(leftChannel.currentLevel)
//    // 输出 "7"
//    println(AudioChannel.maxInputLevelForAllChannels)
//    // 输出 "7"
//
//    rightChannel.currentLevel = 11
//    println(rightChannel.currentLevel)
//    // 输出 "10"
//    println(AudioChannel.maxInputLevelForAllChannels)
//    // 输出 "10"
////}



// MARK: 方法
// MARK: -- 实例方法 Instance Methods
// //{
//    /*
//    实例方法要写在它所属的类型的前后大括号之间。
//    实例方法能够隐式访问它所属类型的所有的其他实例方法和属性。
//    实例方法只能被它所属的类的某个特定实例调用。
//    实例方法不能脱离于现存的实例而被调用。
//    */
//    class Counter {
//        var count = 0
//        func increment() {
//            count++
//        }
//        func incrementBy(amount: Int) {
//            count += amount
//        }
//        func reset() {
//            count = 0
//        }
//    }
//    let counter = Counter()
//    // 初始计数值是0
//    counter.increment()
//    // 计数值现在是1
//    counter.incrementBy(5)
//    // 计数值现在是6
//    counter.reset()
//    // 计数值现在是0
// }

// MARK: ---- self 属性
// //{
// 	/*
// 	类型的每一个实例都有一个隐含属性叫做 self  ， self  完全等同于该实例本身。
// 	*/
// 	struct Point {
// 		var x = 0.0, y = 0.0
// 		func isToTheRightOfX(x: Double) -> Bool {
// 			return self.x > x
// 		}
// 	}
// 	let somePoint = Point(x: 4.0, y: 5.0)
// 	if somePoint.isToTheRightOfX(1.0) {
// 	println("This point is to the right of the line where x == 1.0")
// 	}
// 	// 输出 "This point is to the right of the line where x == 1.0"（这个点在x等于1.0这条线的右边）
// }

// MARK: ---- 在实例方法中修改值类型
// //{
// 	/*
// 	结构体和枚举是值类型。一般情况下，值类型的属性不能在它的实例方法中被修改。
// 	但是，如果你确实需要在某个具体的方法中修改结构体或者枚举的属性，
// 	你可以选择 变异(mutating)  这个方法，然后方法就可以从方法内部改变它的属性；
// 	并且它做的任何改变在方法结束时还会保留在原始结构中。
// 	方法还可以给它隐含的 self  属性赋值一个全新的实例，
// 	这个新实例在方法结束后将替换原来的实例。
// 	*/
// 	/*
// 	要使用 变异  方法， 将关键字 mutating  放到方法的 func  关键字之前就可以了
// 	*/
// 	struct Point {
// 		var x = 0.0, y = 0.0
// 		mutating func moveByX(deltaX: Double, y deltaY: Double) {
// 			x += deltaX
// 			y += deltaY
// 		}
// 	}
// 	var somePoint = Point(x: 1.0, y: 1.0)
// 	somePoint.moveByX(2.0, y: 3.0)
// 	println("The point is now at (\(somePoint.x), \(somePoint.y))")
// 	// 输出 "The point is now at (3.0, 4.0)"

// 	/*
// 	不能在结构体类型常量上调用变异方法
// 	*/
// 	let fixedPoint = Point(x: 3.0, y: 3.0)
// 	fixedPoint.moveByX(2.0, y: 3.0)
// 	// this will report an error
// }

// MARK: ---- 在变异方法中给self复制
// //{
// 	/*
// 	变异方法能够赋给隐含属性 self  一个全新的实例。
// 	*/
// 	struct Point {
// 		var x = 0.0, y = 0.0
// 		mutating func moveByX(deltaX: Double, y deltaY: Double) {
// 			self = Point(x: x + deltaX, y: y + deltaY)
// 		}
// 	}

// 	/*
// 	枚举的变异方法可以把 self  设置为相同的枚举类型中不同的成员
// 	*/
// 		enum TriStateSwitch {
// 		case Off, Low, High
// 			mutating func next() {
// 				switch self {
// 				case Off:
// 					self = Low
// 				case Low:
// 					self = High
// 				case High:
// 					self = Off
// 			}
// 		}
// 	}
// 	var ovenLight = TriStateSwitch.Low
// 	ovenLight.next()
// 	// ovenLight 现在等于 .High
// 	ovenLight.next()
// 	// ovenLight 现在等于 .Off
// }

// MARK: -- 类型方法 Type Methods
// MARK: ---- e.g.1
// //{
// 	/*
// 	声明类的类型方法，在方法的 func  关键字之前加上关键字 class  ；
// 	声明结构体和枚举的类型方法，在方法的 func  关键字之前加上关键字 static  。
// 	*/
// 	class SomeClass {
// 		class func someTypeMethod() {
// 			// type method implementation goes here
// 			/*
// 			在类型方法的方法体（body）中， self  指向这个类型本身，而不是类型的某个实例。
// 			*/
// 		}
// 	}
// 	SomeClass.someTypeMethod()
// }

// MARK: ---- e.g.2
// //{
// 	struct LevelTracker {
// 		static var highestUnlockedLevel = 1
// 		static func unlockLevel(level: Int) {
// 			if level > highestUnlockedLevel { highestUnlockedLevel = level }
// 		}
// 		static func levelIsUnlocked(level: Int) -> Bool {
// 			return level <= highestUnlockedLevel
// 		}
// 		var currentLevel = 1
// 		mutating func advanceToLevel(level: Int) -> Bool {
// 			if LevelTracker.levelIsUnlocked(level) {
// 				currentLevel = level
// 				return true
// 			} else {
// 				return false
// 			}
// 		}
// 	}

// 	class Player {
// 		var tracker = LevelTracker()
// 		let playerName: String
// 		func completedLevel(level: Int) {
// 			LevelTracker.unlockLevel(level + 1)
// 			tracker.advanceToLevel(level + 1)
// 		}
// 		init(name: String) {
// 			playerName = name
// 		}
// 	}

// 	var player = Player(name: "Argyrios")
// 	player.completedLevel(1)
// 	println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// 	// 输出 "highest unlocked level is now 2"（最高等级现在是2）

// 	player = Player(name: "Beto")
// 	if player.tracker.advanceToLevel(6) {
// 		println("player is now on level 6")
// 	} else {
// 		println("level 6 has not yet been unlocked")
// 	}
// 	// 输出 "level 6 has not yet been unlocked"（等级6还没被解锁）
// }



// MARK: 下标脚本 Subscripts
// //{
// 	/*
// 	下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值。
// 	语法类似于实例方法和计算型属性的混合。
// 	与定义实例方法类似，定义下标脚本使用 subscript  关键字，
// 	显式声明入参（一个或多个）和返回类型。
// 	与实例方法不同的是下标脚本可以设定为读写或只读。
// 	这种方式又有点像计算型属性的getter和setter
// 	*/
// 	// subscript(index: Int) -> Int {
// 	// 	get {
// 	// 		// 返回与入参匹配的Int类型的值
// 	// 	}
// 	// 	set(newValue) {
// 	// 		// 执行赋值操作
// 	// 	}
// 	// }

// 	struct TimesTable {
// 		let multiplier: Int
// 		subscript(index: Int) -> Int {
// 			return multiplier * index
// 		}
// 	}
// 	let threeTimesTable = TimesTable(multiplier: 3)
// 	println("3的6倍是\(threeTimesTable[6])")
// 	// 输出 "3的6倍是18"
// }

// MARK: -- 下标脚本选项
// //{
// 	/*
// 	下标脚本允许任意数量的入参索引，并且每个入参类型也没有限制。
// 	下标脚本的返回值也可以是任何类型。
// 	下标脚本可以使用变量参数和可变参数，但使用写入读出（in-out）参数或给参数设置默认值都是不允许的。
// 	*/
// 	struct Matrix {
// 		let rows: Int, columns: Int
// 		var grid: [Double]
// 		init(rows: Int, columns: Int) {
// 			self.rows = rows
// 			self.columns = columns
// 			grid = Array(count: rows * columns, repeatedValue: 0.0)
// 		}
// 		func indexIsValidForRow(row: Int, column: Int) -> Bool {
// 			return row >= 0 && row < rows && column >= 0 && column < columns
// 		}
// 		subscript(row: Int, column: Int) -> Double {
// 			get {
// 				assert(indexIsValidForRow(row, column: column), "Index out of range")
// 				return grid[(row * columns) + column]
// 			}
// 			set {
// 				assert(indexIsValidForRow(row, column: column), "Index out of range")
// 				grid[(row * columns) + column] = newValue
// 			}
// 		}
// 	}

// 	var matrix = Matrix(rows: 2, columns: 2)
// 	matrix[0, 1] = 1.5
// 	matrix[1, 0] = 3.2

// 	let someValue = matrix[2, 2]
// 	// 断言将会触发，因为 [2, 2] 已经超过了matrix的最大长度
// }


// MARK: 继承 Inheritance
/*
在 Swift 中，类可以调用和访问超类的方法，属性和下标脚本（subscripts），
并且可以重写（override）这些方法，属性和下标脚本来优化或修改它们的行为。
Swift 会检查你的重写定义在超类中是否有匹配的定义，以此确保你的重写行为是正确的。
可以为类中继承来的属性添加属性观察器（property observer），这样一来，当属性值改变时，类就会被通知到。
可以为任何属性添加属性观察器，无论它原本被定义为存储型属性（stored property）还是计算型属性（computed property）。
*/
// MARK: -- 定义一个基类 Base class
// //{
// 	/*
// 	Swift 中的类并不是从一个通用的基类继承而来。
// 	如果你不为你定义的类指定一个超类的话，这个类就自动成为基类。
// 	*/
// 	class Vehicle {
// 		var currentSpeed = 0.0
// 		var description: String {
// 		return "traveling at \(currentSpeed) miles per hour"
// 		}
// 		func makeNoise() {
// 		// 什么也不做-因为车辆不一定会有噪音
// 		}
// 	}
// 	let someVehicle = Vehicle()
// 	println("Vehicle: \(someVehicle.description)")
// 	// Vehicle: traveling at 0.0 miles per hour

// 	// MARK: -- 子类生成 Subclassing
// 	// class SomeClass: SomeSuperclass {
// 	// 	// 类的定义
// 	// }

// 	class Bicycle: Vehicle {
// 		var hasBasket = false
// 	}
// 	let bicycle = Bicycle()
// 	bicycle.hasBasket = true

// 	bicycle.currentSpeed = 15.0
// 	println("Bicycle: \(bicycle.description)")
// 	// Bicycle: traveling at 15.0 miles per hour

// 	// MARK: -- 重写 Overriding
// 	/*
// 	子类可以为继承来的实例方法（instance method），类方法（class method），
// 	实例属性（instance property），或下标脚本（subscript）提供自己定制的实现（implementation）。
// 	我们把这种行为叫重写（overriding）。

// 	如果要重写某个特性，你需要在重写定义的前面加上 override  关键字。
// 	在合适的地方，你可以通过使用 super  前缀来访问超类版本的方法，属性或下标脚本
// 	*/

// 	// MARK: ---- 重写方法
// 	class Train: Vehicle {
// 		override func makeNoise() {
// 			println("Choo Choo")
// 		}
// 	}
// 	let train = Train()
// 	train.makeNoise()
// 	// prints "Choo Choo"

// 	// MARK: ---- 重写属性的Getters Setters
// 	/*
// 	你可以将一个继承来的只读属性重写为一个读写属性，
// 	只需要你在重写版本的属性里提供 getter 和 setter 即可。
// 	但是，你不可以将一个继承来的读写属性重写为一个只读属性。
// 	*/
// 	class Car: Vehicle {
// 		var gear = 1
// 		override var description: String {
// 			return super.description + " in gear \(gear)"
// 		}
// 	}
// 	let car = Car()
// 	car.currentSpeed = 25.0
// 	car.gear = 3
// 	println("Car: \(car.description)")
// 	// Car: traveling at 25.0 miles per hour in gear 3

// 	// MARK: ---- 重写属性观察器
// 	/*
// 	你可以在属性重写中为一个继承来的属性添加属性观察器。
// 	这样一来，当继承来的属性值发生改变时，你就会被通知到，无论那个属性原本是如何实现的。
// 	*/
// 	class AutomaticCar: Car {
// 		override var currentSpeed: Double {
// 			didSet {
// 				gear = Int(currentSpeed / 10.0) + 1
// 			}
// 		}
// 	}
// 	let automatic = AutomaticCar()
// 	automatic.currentSpeed = 35.0
// 	println("AutomaticCar: \(automatic.description)")
// 	// AutomaticCar: traveling at 35.0 miles per hour in gear 4

// 	// MARK: ---- 防止重写
// 	/*
// 	你可以通过把方法，属性或下标脚本标记为 final  来防止它们被重写

// 	你可以通过在关键字 class  前添加 final  特性（ final class  ）
// 	来将整个类标记为 final 的，这样的类是不可被继承的
// 	*/
// }



// MARK: 构造过程 Initialization
/*
与Objective-C 中的构造器不同，Swift 的构造器无需返回值
*/
// MARK: -- 存储型属性的初始赋值
/*
类和结构体在实例创建时，必须为所有存储型属性设置合适的初始值。
存储型属性的值不能处于一个未知的状态。
*/
// MARK: ---- 构造器
// //{
// 	struct Fahrenheit {
// 		var temperature: Double
// 		init() {
// 			temperature = 32.0
// 		}
// 	}
// 	var f = Fahrenheit()
// 	println("The default temperature is \(f.temperature)° Fahrenheit")
// 	// 输出 "The default temperature is 32.0° Fahrenheit”
// }

// MARK: ---- 默认属性值

// MARK: ---- 定制化构造过程
// //{
// 	struct Celsius {
// 		var temperatureInCelsius: Double = 0.0
// 		init(fromFahrenheit fahrenheit: Double) {
// 			temperatureInCelsius = (fahrenheit - 32.0) / 1.8
// 		}
// 		init(fromKelvin kelvin: Double) {
// 			temperatureInCelsius = kelvin - 273.15
// 		}
// 	}
// 	let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// 	// boilingPointOfWater.temperatureInCelsius 是 100.0
// 	let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// 	// freezingPointOfWater.temperatureInCelsius 是 0.0”

// }

// MARK: ---- 可选属性类型 Optional Type
// //{
// 	class SurveyQuestion {
// 		var text: String
// 		var response: String?
// 		init(text: String) {
// 			self.text = text
// 		}
// 		func ask() {
// 			println(text)
// 		}
// 	}
// 	let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
// 	cheeseQuestion.ask()
// 	// 输出 "Do you like cheese?"
// 	cheeseQuestion.response = "Yes, I do like cheese."
// }

// MARK: ---- 构造过程中常量属性的修改
/*
只要在构造过程结束前常量的值能确定，你可以在构造过程中的任意时间点修改常量属性的值。

对某个类实例来说，它的常量属性只能在定义它的类的构造过程中修改；不能在子类中修改。
*/
// //{
// 	class SurveyQuestion {
// 		let text: String
// 		var response: String?
// 			init(text: String) {
// 			self.text = text
// 		}
// 		func ask() {
// 			println(text)
// 		}
// 	}
// 	let beetsQuestion = SurveyQuestion(text: "How about beets?")
// 	beetsQuestion.ask()
// 	// 输出 "How about beets?"
// 	beetsQuestion.response = "I also like beets. (But not with cheese.)"
// }

// MARK: ---- 值类型构造器代理
// //{
// 	struct Rect {
// 		var origin = Point()
// 		var size = Size()
// 		init() {}
// 		init(origin: Point, size: Size) {
// 			self.origin = origin
// 			self.size = size
// 		}
// 		init(center: Point, size: Size) {
// 			let originX = center.x - (size.width / 2)
// 			let originY = center.y - (size.height / 2)
// 			self.init(origin: Point(x: originX, y: originY), size: size)
// 		}
// 	}

// 	/*
// 	构造器 init()
// 	在功能上跟没有自定义构造器时自动获得的默认构造器是一样的
// 	*/
// 	let basicRect = Rect()
// 	// basicRect 的原点是 (0.0, 0.0)，尺寸是 (0.0, 0.0)

// 	/*
// 	 构造器 init(origin:size:)
// 	 在功能上跟结构体在没有自定义构造器时获得的逐一成员构造器是一样的。
// 	*/
// 	let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
// 							size: Size(width: 5.0, height: 5.0))
// 	// originRect 的原点是 (2.0, 2.0)，尺寸是 (5.0, 5.0)

// 	/*
// 	构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理
// 	*/
// 	let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
// 							size: Size(width: 3.0, height: 3.0))
// 	// centerRect 的原点是 (2.5, 2.5)，尺寸是 (3.0, 3.0)
// }


// MARK: -- 类的继承和构造过程
/*
Swift 提供了两种类型的类构造器来确保所有类实例中存储型属性都能获得初始值，
它们分别是指定构造器和便利构造器。
*/

// MARK: ---- 指定构造器和便利构造器
/*
指定构造器是类中最主要的构造器。
一个指定构造器将初始化类中提供的所有属性，并根据父类链往上调用父类的构造器来实现父类的初始化。

可以定义便利构造器来调用同一个类中的指定构造器，并为其参数提供默认值。
你也可以定义便利构造器来创建一个特殊用途或特定输入的实例。

Swift 采用以下三条规则来限制构造器之间的代理调用：
* 指定构造器必须调用其直接父类的的指定构造器
* 便利构造器必须调用同一类中定义的其它构造器
* 便利构造器必须最终以调用一个指定构造器结束
*/

// MARK: ---- 两段式构造过程
/*
Swift 中类的构造过程包含两个阶段。
第一个阶段，每个存储型属性通过引入它们的类的构造器来设置初始值。
当每一个存储型属性值被确定后，第二阶段开始，
它给每个类一次机会在新实例准备使用之前进一步定制它们的存储型属性。
*/

// MARK: ---- 构造器的继承和重载
/*
跟 Objective-C 中的子类不同，Swift 中的子类不会默认继承父类的构造器。

*/
// //{
// 	/*
// 	语法
// 	init(parameters) {
// 		statements
// 	}

// 	convenience init(parameters) {
// 		statements
// 	}
// 	*/
// 	class Food {
// 		var name: String
// 		//指定构造器
// 		init(name: String) {
// 			self.name = name
// 		}
// 		//便利构造器
// 		convenience init() {
// 			self.init(name: "[Unnamed]")
// 		}
// 	}
// 	//调用指定构造器
// 	let namedMeat = Food(name: "Bacon")
// 	// namedMeat 的名字是 "Bacon”

// 	//调用便利构造器
// 	let mysteryMeat = Food()
// 	// mysteryMeat 的名字是 [Unnamed]


// 	class RecipeIngredient: Food {
// 		var quantity: Int
// 		init(name: String, quantity: Int) {
// 			self.quantity = quantity
// 			super.init(name: name)
// 		}
// 		/*
// 		使用了跟 Food  中指定构造器 init(name: String)  相同的参数。
// 		因为这个便利构造器重写父类的指定构造器 init(name: String)  ，
// 		必须在前面使用使用 override  标识。
// 		*/
// 		override convenience init(name: String) {
// 			self.init(name: name, quantity: 1)
// 		}
// 	}
// 	let oneMysteryItem = RecipeIngredient()
// 	let oneBacon = RecipeIngredient(name: "Bacon")
// 	let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)


// 	/*
// 	由于它为自己引入的所有属性都提供了默认值，并且自己没有定义任何构造器，
// 	ShoppingListItem  将自动继承所有父类中的指定构造器和便利构造器
// 	*/
// 	class ShoppingListItem: RecipeIngredient {
// 		var purchased = false
// 		var description: String {
// 			var output = "\(quantity) x \(name.lowercaseString)"
// 			output += purchased ? " y" : " n"
// 			return output
// 		}
// 	}

// 	var breakfastList = [
// 		ShoppingListItem(),
// 		ShoppingListItem(name: "Bacon"),
// 		ShoppingListItem(name: "Eggs", quantity: 6),
// 	]
// 	breakfastList[0].name = "Orange juice"
// 	breakfastList[0].purchased = true
// 	for item in breakfastList {
// 		println(item.description)
// 	}
// 	// 1 x orange juice y
// 	// 1 x bacon n
// 	// 6 x eggs n
// }

// MARK: ---- 可失败构造器
// //{
// 	struct Animal {
// 		let species: String
// 		init?(species: String) {
// 			if species.isEmpty {
// 				return nil
// 			}
// 			self.species = species
// 		}
// 	}

// 	let someCreature = Animal(species: "Giraffe")
// 	// someCreature 的类型是 Animal? 而不是 Animal
// 	if let giraffe = someCreature {
// 		println("An animal was initialized with a species of \(giraffe.species)")
// 	}
// 	// 打印 "An animal was initialized with a species of Giraffe"

// 	let anonymousCreature = Animal(species: "")
// 	// anonymousCreature 的类型是 Animal?, 而不是 Animal
// 	if anonymousCreature == nil {
// 		println("The anonymous creature could not be initialized")
// 	}
// 	// 打印 "The anonymous creature could not be initialized"
// }

// MARK: ---- 枚举类型的可失败构造器
// //{
// 	enum TemperatureUnit {
// 		case Kelvin, Celsius, Fahrenheit
// 		init?(symbol: Character) {
// 			switch symbol {
// 				case "K":
// 					self = .Kelvin
// 				case "C":
// 					self = .Celsius
// 				case "F":
// 					self = .Fahrenheit
// 				default:
// 					return nil
// 			}
// 		}
// 	}

// 	let fahrenheitUnit = TemperatureUnit(symbol: "F")
// 	if fahrenheitUnit != nil {
// 		println("This is a defined temperature unit, so initialization succeeded.")
// 	}
// 	// 打印 "This is a defined temperature unit, so initialization succeeded."
// 	let unknownUnit = TemperatureUnit(symbol: "X")
// 	if unknownUnit == nil {
// 		println("This is not a defined temperature unit, so initialization failed.")
// 	}
// 	// 打印 "This is not a defined temperature unit, so initialization failed."
// }

// MARK: ---- 带原始值的枚举类型的可失败构造器
/*
带原始值的枚举类型会自带一个可失败构造器 init?(rawValue:)  ,
该可失败构造器有一个名为 rawValue  的默认参数,其类型和枚举类型的原始值类型一致，
如果该参数的值能够和枚举类型成员所带的原始值匹配，
则该构造器构造一个带此原始值的枚举成员，否则构造失败。
*/
// //{
// 	enum TemperatureUnit: Character {
// 		case Kelvin = "K", Celsius = "C", Fahrenheit = "F"
// 	}

// 	let fahrenheitUnit = TemperatureUnit(rawValue: "F")
// 	if fahrenheitUnit != nil {
// 		println("This is a defined temperature unit, so initialization succeeded.")
// 	}
// 	// prints "This is a defined temperature unit, so initialization succeeded."
// 	let unknownUnit = TemperatureUnit(rawValue: "X")
// 	if unknownUnit == nil {
// 		println("This is not a defined temperature unit, so initialization failed.")
// 	}
// 	// prints "This is not a defined temperature unit, so initialization failed."
// }

// MARK: ---- 类的可失败构造器
/*
类的可失败构造器只能在所有的类属性被初始化后
和所有类之间的构造器之间的代理调用发生完后触发失败行为。
*/
// //{
// 	class Product {
// 		/*
// 		 name 属性改为隐式解析可选类型,
// 		来确保可失败构造器触发失败条件时，所有类属性都被初始化了。
// 		*/
// 		let name: String!
// 		init?(name: String) {
// 			if name.isEmpty { return nil }
// 			self.name = name
// 		}
// 	}
// 	if let bowTie = Product(name: "bow tie") {
// 		// 不需要检查 bowTie.name == nil
// 		println("The product's name is \(bowTie.name)")
// 	}
// 	// 打印 "The product's name is bow tie"
// }

// MARK: ---- 构造失败的传递
// //{
// 	class CartItem: Product {
// 	let quantity: Int!
// 	init?(name: String, quantity: Int) {
// 			super.init(name: name)
// 			if quantity < 1 { return nil }
// 			self.quantity = quantity
// 		}
// 	}
// 	if let twoSocks = CartItem(name: "sock", quantity: 2) {
// 		println("Item: \(twoSocks.name), quantity: \(twoSocks.quantity)")
// 	}
// 	// 打印 "Item: sock, quantity: 2"

// 	if let zeroShirts = CartItem(name: "shirt", quantity: 0) {
// 		println("Item: \(zeroShirts.name), quantity: \(zeroShirts.quantity)")
// 	} else {
// 		println("Unable to initialize zero shirts")
// 	}
// 	// 打印 "Unable to initialize zero shirts"

// 	if let oneUnnamed = CartItem(name: "", quantity: 1) {
// 		println("Item: \(oneUnnamed.name), quantity: \(oneUnnamed.quantity)")
// 	} else {
// 		println("Unable to initialize one unnamed product")
// 	}
// 	// 打印 "Unable to initialize one unnamed product"
// }

// MARK: ---- 覆盖一个可失败构造器
/*
可以用子类的可失败构造器覆盖基类的可失败构造器。
或者你也可以用子类的非可失败构造器覆盖一个基类的可失败构造器。

你可以用一个非可失败构造器覆盖一个可失败构造器，但反过来却行不通。
*/
// //{
// 	class Document {
// 		var name: String?
// 		// 该构造器构建了一个name属性值为nil的document对象
// 		init() {}
// 		// 该构造器构建了一个name属性值为非空字符串的document对象
// 		init?(name: String) {
// 			if name.isEmpty { return nil }
// 			self.name = name
// 		}
// 	}

// 	class AutomaticallyNameDocument: Document {
// 		override init() {
// 			super.init()
// 			self.name = "[Untitled]"
// 		}
// 		override init(name: String) {
// 			super.init()
// 			if name.isEmpty {
// 				self.name = "[Untitled]"
// 			} else {
// 				self.name = name
// 			}
// 		}
// 	}
// }

// MARK: ---- 必要构造器
/*
在类的构造器前添加```required```修饰符表明所有该类的子类都必须实现该构造器

当子类覆盖基类的必要构造器时，
必须在子类的构造器前同样添加 required  修饰符以确保当其它类继承该子类时，
该构造器同为必要构造器。
在覆盖基类的必要构造器时，不需要添加 override  修饰符
*/
// //{
// 	class SomeClass {
// 		required init() {
// 			// 在这里添加该必要构造器的实现代码
// 		}
// 	}

// 	class SomeSubClass: SomeClass {
// 		required init() {
// 			// 在这里添加子类必要构造器的实现代码
// 		}
// 	}

// 	/*
// 	如果子类继承的构造器能满足必要构造器的需求，
// 	则你无需显示的在子类中提供必要构造器的实现
// 	*/
// }


// MARK: -- 通过闭包和函数来设置属性的默认值
/*
如果某个存储型属性的默认值需要特别的定制或准备，
你就可以使用闭包或全局函数来为其属性提供定制的默认值。
每当某个属性所属的新类型实例创建时，对应的闭包或函数会被调用，
而它们的返回值会当做默认值赋值给这个属性。

如果你使用闭包来初始化属性的值，请记住在闭包执行时，实例的其它部分都还没有初始化。
这意味着你不能够在闭包里访问其它的属性，就算这个属性有默认值也不允许。
同样，你也不能使用隐式的 self  属性，或者调用其它的实例方法。
*/
// //{
// 	class SomeClass {
// 		let someProperty: SomeType = {
// 			// 在这个闭包中给 someProperty 创建一个默认值
// 			// someValue 必须和 SomeType 类型相同
// 			return someValue
// 			}()
// 		/*
// 		注意闭包结尾的大括号后面接了一对空的小括号。
// 		这是用来告诉 Swift 需要立刻执行此闭包。
// 		如果你忽略了这对括号，相当于是将闭包本身作为值赋值给了属性，
// 		而不是将闭包的返回值赋值给属性。
// 		*/
// 	}
// }

// MARK: ---- e.g.1
// //{
// 	struct Checkerboard {
// 		let boardColors: [Bool] = {
// 			var temporaryBoard = [Bool]()
// 			var isBlack = false
// 			for i in 1...10 {
// 				for j in 1...10{
// 					temporaryBoard.append(isBlack)
// 					isBlack = !isBlack
// 				}
// 				isBlack = !isBlack
// 			}
// 			return temporaryBoard
// 			}()
// 		func squareIsBlackAtRow(row: Int, column: Int) -> Bool {
// 			return boardColors[(row * 10) + column]
// 		}
// 	}

// 	let board = Checkerboard()
// 	println(board.squareIsBlackAtRow(0, column: 1))
// 	// 输出 "true"
// 	println(board.squareIsBlackAtRow(9, column: 9))
// 	// 输出 "false"
// }



// MARK: 析构过程 Deinitialization
/*
在一个类的实例被释放之前，析构函数被立即调用。
用关键字 deinit  来标示析构函数，类似于初始化函数用 init  来标示。
析构函数只适用于类类型。

析构函数是在实例释放发生前一步被自动调用。不允许主动调用自己的析构函数。
*/
/*
在类的定义中，每个类最多只能有一个析构函数。析构函数不带任何参数，在写法上不带括号
*/
// //{
// 	struct Bank {
// 		static var coinsInBank = 10_000
// 		static func vendCoins(var numberOfCoinsToVend: Int) -> Int {
// 			numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
// 			coinsInBank -= numberOfCoinsToVend
// 			return numberOfCoinsToVend
// 		}
// 		static func receiveCoins(coins: Int) {
// 			coinsInBank += coins
// 		}
// 	}
// 	class Player {
// 		var coinsInPurse: Int
// 		init(coins: Int) {
// 			coinsInPurse = Bank.vendCoins(coins)
// 		}
// 		func winCoins(coins: Int) {
// 			coinsInPurse += Bank.vendCoins(coins)
// 		}
// 		deinit {
// 			Bank.receiveCoins(coinsInPurse)
// 		}
// 	}

// 	var playerOne: Player? = Player(coins: 100)
// 	println("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// 	// 输出 "A new player has joined the game with 100 coins"
// 	println("There are now \(Bank.coinsInBank) coins left in the bank")
// 	// 输出 "There are now 9900 coins left in the bank"

// 	playerOne!.winCoins(2_000)
// 	println("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// 	// 输出 "PlayerOne won 2000 coins & now has 2100 coins"
// 	println("The bank now only has \(Bank.coinsInBank) coins left")
// 	// 输出 "The bank now only has 7900 coins left"

// 	playerOne = nil
// 	println("PlayerOne has left the game")
// 	// 输出 "PlayerOne has left the game"
// 	println("The bank now has \(Bank.coinsInBank) coins")
// 	// 输出 "The bank now has 10000 coins"
// }



// MARK: 自动引用计数
// //{
// 	class Person {
// 		let name: String
// 		init(name: String) {
// 			self.name = name
// 			println("\(name) is being initialized")
// 		}
// 		deinit {
// 			println("\(name) is being deinitialized")
// 		}
// 	}
// 	var reference1: Person?
// 	var reference2: Person?
// 	var reference3: Person?
// 	// ARC =0

// 	reference1 = Person(name: "John Appleseed")
// 	// prints "John Appleseed is being initialized”
// 	// ARC +1=1

// 	reference2 = reference1
// 	reference3 = reference1
// 	// ARC +2=3

// 	reference1 = nil
// 	reference2 = nil
// 	// ARC -2=1

// 	reference3 = nil
// 	// ARC -1=0
// 	// prints "John Appleseed is being deinitialized"
// }

// MARK: -- 类实例之间的循环强引用
// //{
// 	class Person {
// 		let name: String
// 		init(name: String) { self.name = name }
// 		var apartment: Apartment?
// 		deinit { println("\(name) is being deinitialized") }
// 	}
// 	class Apartment {
// 		let number: Int
// 		init(number: Int) { self.number = number }
// 		var tenant: Person?
// 		deinit { println("Apartment #\(number) is being deinitialized") }
// 	}

// 	var john: Person?
// 	var number73: Apartment?

// 	john = Person(name: "John Appleseed")
// 	number73 = Apartment(number: 73)

// 	/*
// 	注意感叹号是用来展开和访问可选变量 john  和 number73  中的实例，
// 	这样实例的属性才能被赋值
// 	*/
// 	john!.apartment = number73
// 	number73!.tenant = john

// 	/*
// 	强引用循环阻止了 Person  和 Apartment  类实例的销毁，
// 	并在你的应用程序中造成了内存泄漏。
// 	*/
// 	john = nil
// 	number73 = nil
// }

// MARK: ---- 解决实例之间的循环强引用
/*
Swift 提供了两种办法用来解决你在使用类的属性时所遇到的循环强引用问题：
弱引用（weak reference）和无主引用（unowned reference）。

弱引用和无主引用允许循环引用中的一个实例引用另外一个实例而不保持强引用。
这样实例能够互相引用而不产生循环强引用。

对于生命周期中会变为 nil  的实例使用弱引用。
相反的，对于初始化赋值后再也不会被赋值为 nil  的实例，使用无主引用。
*/

// MARK: ---- 弱引用
/*
弱引用不会牢牢保持住引用的实例，并且不会阻止 ARC 销毁被引用的实例。
这种行为阻止了引用变为循环强引用。声明属性或者变量时，在前面加上 weak  关键字表明这是一个弱引用。

在实例的生命周期中，如果某些时候引用没有值，那么弱引用可以阻止循环强引用。

弱引用必须被声明为变量，表明其值能在运行时被修改。弱引用不能被声明为常量。
因为弱引用可以没有值，你必须将每一个弱引用声明为可选类型。
*/
// //{
// 	class Person {
// 		let name: String
// 		init(name: String) { self.name = name }
// 		var apartment: Apartment?
// 		deinit { println("\(name) is being deinitialized") }
// 	}
// 	class Apartment {
// 		let number: Int
// 		init(number: Int) { self.number = number }
// 		weak var tenant: Person?
// 		deinit { println("Apartment #\(number) is being deinitialized") }
// 	}

// 	var john: Person?
// 	var number73: Apartment?

// 	john = Person(name: "John Appleseed")
// 	number73 = Apartment(number: 73)

// 	john!.apartment = number73
// 	number73!.tenant = john

// 	/*
// 	Person  实例依然保持对 Apartment  实例的强引用，
// 	但是 Apartment  实例只是对 Person  实例的弱引用。
// 	这意味着当你断开 john  变量所保持的强引用时，再也没有指向 Person  实例的强引用了
// 	*/
// 	john = nil
// 	/*
// 	由于再也没有指向 Person  实例的强引用，该实例会被销毁
// 	*/
// 	// prints "John Appleseed is being deinitialized"

// 	/*
// 	随着Person  实例john的销毁,其对Apartment  实例number73的强引用也被销毁
// 	*/
// 	number73 = nil
// 	/*
// 	由于再也没有指向 Apartment  实例的强引用，该实例也会被销毁
// 	*/
// 	// prints "Apartment #73 is being deinitialized"
// }

// MARK: ---- 无主引用
/*
和弱引用不同的是，无主引用是永远有值的。
因此，无主引用总是被定义为非可选类型（non-optional type）。
你可以在声明属性或者变量时，在前面加上关键字 unowned  表示这是一个无主引用。

ARC 无法在实例被销毁后将无主引用设为 nil  ，因为非可选类型的变量不允许被赋值为 nil  。
如果你试图访问实例已经被销毁的无主引用，程序会直接崩溃
*/
// //{
// 	class Customer {
// 		let name: String
// 		var card: CreditCard?
// 		init(name: String) {
// 			self.name = name
// 		}
// 		deinit { println("\(name) is being deinitialized") }
// 	}
// 	class CreditCard {
// 		let number: Int
// 		unowned let customer: Customer
// 		init(number: Int, customer: Customer) {
// 			self.number = number
// 			self.customer = customer
// 		}
// 		deinit { println("Card #\(number) is being deinitialized") }
// 	}

// 	var john: Customer?
// 	john = Customer(name: "John Appleseed")
// 	john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// 	/*
// 	Customer  实例持有对 CreditCard  实例的强引用，
// 	而 CreditCard  实例持有对 Customer  实例的无主引用。
// 	*/

// 	john = nil
// 	/*
// 	由于再也没有指向 Customer  实例的强引用，该实例被销毁了。
// 	其后，再也没有指向 CreditCard  实例的强引用，该实例也随之被销毁了
// 	*/
// 	// prints "John Appleseed is being deinitialized"
// 	// prints "Card #1234567890123456 is being deinitialized"
// }

// MARK: ---- 无主引用以及隐式解析可选属性
/*
两个属性都必须有值，并且初始化完成后不能为 nil  。
在这种场景中，需要一个类使用无主属性，而另外一个类使用隐式解析可选属性。
*/
// //{
// 	class Country {
// 		let name: String
// 		let capitalCity: City!
// 		init(name: String, capitalName: String) {
// 			self.name = name
// 			self.capitalCity = City(name: capitalName, country: self)
// 		}
// 	}
// 	class City {
// 		let name: String
// 		unowned let country: Country
// 		init(name: String, country: Country) {
// 			self.name = name
// 			self.country = country
// 		}
// 	}

// 	var country = Country(name: "Canada", capitalName: "Ottawa")
// 	println("\(country.name)'s capital city is called \(country.capitalCity.name)")
// 	// prints "Canada's capital city is called Ottawa"
// }


// MARK: -- 闭包引起的循环强引用
/*
循环强引用还会发生在当你将一个闭包赋值给类实例的某个属性，并且这个闭包体中又使用了实例。
这个闭包体中可能访问了实例的某个属性，例如 self.someProperty  ，
或者闭包中调用了实例的某个方法，例如 self.someMethod  。
这两种情况都导致了闭包 “捕获"  self  ，从而产生了循环强引用
*/
////{
//    class HTMLElement {
//        let name: String
//        let text: String?
//        lazy var asHTML: () -> String = {
//            if let text = self.text {
//                return "<\(self.name)>\(text)</\(self.name)>"
//            } else {
//                return "<\(self.name) />"
//            }
//        }
//        init(name: String, text: String? = nil) {
//            self.name = name
//            self.text = text
//        }
//        deinit {
//            println("\(name) is being deinitialized")
//        }
//    }
//    
//    var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
//    println(paragraph!.asHTML())
//    // prints"hello, world"
//    
//    /*
//    实例的 asHTML  属性持有闭包的强引用。
//    但是，闭包在其闭包体内使用了 self  （引用了 self.name  和 self.text  ），
//    因此闭包捕获了 self  ，这意味着闭包又反过来持有了 HTMLElement  实例的强引用。
//    这样两个对象就产生了循环强引用。
//    
//    如果设置 paragraph  变量为 nil  ，打破它持有的 HTMLElement  实例的强引用，
//    HTMLElement  实例和它的闭包都不会被销毁
//    */
//    paragraph = nil
//    // 这里没有触发析构方法
////}

// MARK: ---- 解决闭包引起的循环强引用
/*
在定义闭包时同时定义捕获列表作为闭包的一部分，
通过这种方式可以解决闭包和类实例之间的循环强引用。
捕获列表定义了闭包体内捕获一个或者多个引用类型的规则。
跟解决两个类实例间的循环强引用一样，声明每个捕获的引用为弱引用或无主引用，而不是强引用。
*/

// MARK: ---- 定义捕获列表
////{
//    /*
//    捕获列表中的每个元素都是由 weak  或者 unowned  关键字和实例的引用（如 self  或 someInstance  ）成对组成。
//    每一对都在方括号中，通过逗号分开。
//    */
//    lazy var someClosure: (Int, String) -> String = {
//        [unowned self] (index: Int, stringToProcess: String) -> String in
//        // closure body goes here
//    }
//    
//    
//    /*
//    如果闭包没有指定参数列表或者返回类型，则可以通过上下文推断，
//    那么可以捕获列表放在闭包开始的地方，跟着是关键字 in
//    */
//    lazy var someClosure: () -> String = {
//        [unowned self] in
//        // closure body goes here
//    }
////}

// MARK: ---- 弱引用和无主引用
/*
当闭包和捕获的实例总是互相引用时并且总是同时销毁时，将闭包内的捕获定义为无主引用。

相反的，当捕获引用有时可能会是 nil  时，将闭包内的捕获定义为弱引用。
弱引用总是可选类型，并且当引用的实例被销毁后，弱引用的值会自动置为 nil  。
这使我们可以在闭包内检查它们是否存在。

如果捕获的引用绝对不会置为 nil  ，应该用无主引用，而不是弱引用。
*/
//////{
//class HTMLElement {
//    let name: String
//    let text: String?
//    
//    lazy var asHTML: () -> String = {
//        [unowned self] in
//        if let text = self.text {
//            return "<\(self.name)>\(text)</\(self.name)>"
//        } else {
//            return "<\(self.name) />"
//        }
//    }
//    init(name: String, text: String? = nil) {
//        self.name = name
//        self.text = text
//    }
//    deinit {
//        println("\(name) is being deinitialized")
//    }
//}
//
//var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
//println(paragraph!.asHTML())
//// prints "<p>hello, world</p>"
//
///*
//闭包无主引用的形式捕获self,并不会持有HTMLElement实例的强引用。
//如果将paragraph设置为nil,HTMLElement实例将会被销毁
//*/
//paragraph = nil
//// prints "p is being deinitialized"
//////}



// MARK: 可选链  Optional Chaining
/*
可选链是一种可以请求和调用属性、方法及下标脚本的过程，
它的可选性体现于请求或调用的目标当前可能为空(nil)。

如果可选的目标有值，那么调用就会成功；如果选择的目标为空，则调用将返回空。

多次请求或调用可以被链接在一起形成一个链，如果任一节点为空将导致整个链失效。

Swift的可选链和Objective-C中的消息为空有些相像，
但Swift可以使用在任意类型中，并且失败与否可以被检测到。
*/

// MARK: -- 可选链可替代强制解析
////{
//class Person {
//    var residence: Residence?
//}
//
//class Residence {
//    var numberOfRooms = 1
//}
//
//let john = Person()
////    let roomCount = john.residence!.numberOfRooms
//if let roomCount = john.residence?.numberOfRooms {
//    println("John's residence has \(roomCount) room(s).")
//} else {
//    println("Unable to retrieve the number of rooms.")
//}
//// 打印 "Unable to retrieve the number of rooms.
//
//john.residence = Residence()
//if let roomCount = john.residence?.numberOfRooms {
//    println("John's residence has \(roomCount) room(s).")
//} else {
//    println("Unable to retrieve the number of rooms.")
//}
//// 打印 "John's residence has 1 room(s)"
////}

// MARK: -- 为可选链定义模型类
////{
//class Person {
//    var residence: Residence?
//}
//
//class Residence {
//    var rooms = [Room]()
//    var numberOfRooms: Int {
//        return rooms.count
//    }
//    subscript(i: Int) -> Room {
//        return rooms[i]
//    }
//    func printNumberOfRooms() {
//        println("The number of rooms is \(numberOfRooms)")
//    }
//    
//    var address: Address?
//}
//
//class Room {
//    let name: String
//    init(name: String) { self.name = name }
//}
//
//class Address {
//    var buildingName: String?
//    var buildingNumber: String?
//    var street: String?
//    func buildingIdentifier() -> String? {
//        if buildingName != nil {
//            return buildingName
//        } else if (buildingNumber != nil) {
//            return buildingNumber
//        } else {
//            return nil
//        }
//    }
//}
//
//// MARK: -- 通过可选链调用属性
///*
//你可以利用可选链的可选值获取属性，并且检查属性是否获取成功。
//然而，你不能使用可选链为属性赋值。
//*/
//let john = Person()
//if let roomCount = john.residence?.numberOfRooms {
//    println("John's residence has \(roomCount) room(s).")
//} else {
//    println("Unable to retrieve the number of rooms.")
//}
//// 打印 "Unable to retrieve the number of rooms
//
//// MARK: -- 通过可选链调用方法
//if (john.residence?.printNumberOfRooms() != nil) {
//    println("It was possible to print the number of rooms.")
//} else {
//    println("It was not possible to print the number of rooms.")
//}
//
//// MARK: -- 使用可选链调用下标脚本
///*
//可以使用可选链来尝试从下标脚本获取值并检查下标脚本的调用是否成功，
//但不能通过可选链来设置下标脚本
//*/
//if let firstRoomName = john.residence?[0].name {
//    println("The first room name is \(firstRoomName).")
//} else {
//    println("Unable to retrieve the first room name.")
//}
//
//let johnsHouse = Residence()
////johnsHouse.rooms += Room(name: "Living Room")
//johnsHouse.rooms.append(Room(name: "Living Room"))
////johnsHouse.rooms += Room(name: "Kitchen")
//johnsHouse.rooms.append(Room(name: "Kitchen"))
//john.residence = johnsHouse
//
//if let firstRoomName = john.residence?[0].name {
//    println("The first room name is \(firstRoomName).")
//} else {
//    println("Unable to retrieve the first room name.")
//}
//
//// MARK: -- 链接多层可选链
///*
//如果你试图获得的类型不是可选类型，由于使用了可选链它将变成可选类型。 
//如果你试图获得的类型已经是可选类型，由于可选链它也不会提高可选性。
//*/
//if let johnsStreet = john.residence?.address?.street {
//    println("John's street name is \(johnsStreet).")
//} else {
//    println("Unable to retrieve the address.")
//}
//
//let johnsAddress = Address()
//johnsAddress.buildingName = "The Larches"
//johnsAddress.street = "Laurel Street"
//john.residence!.address = johnsAddress
//
//if let johnsStreet = john.residence?.address?.street {
//    println("John's street name is \(johnsStreet).")
//} else {
//    println("Unable to retrieve the address.")
//}
//
//// MARK: -- 链接可选返回值的方法
//if let buildingIdentifier = john.residence?.address?.buildingIdentifier() {
//    println("John's building identifier is \(buildingIdentifier).")
//}
//
///*
//如果你还想进一步对方法返回值执行可选链，将可选链问号符放在方法括号的后面：
//*/
//if let upper = john.residence?.address?.buildingIdentifier()?.uppercaseString {
//    println("John's uppercase building identifier is \(upper).")
//}
////}



// MARK: 类型转换 Type Casting
/*
类型转换在 Swift 中使用 is  和  as  操作符实现。
*/
////{
//class MediaItem {
//    var name: String
//    init(name: String) {
//        self.name = name
//    }
//}
//
//class Movie: MediaItem {
//    var director: String
//    init(name: String, director: String) {
//        self.director = director
//        super.init(name: name)
//    }
//}
//
//class Song: MediaItem {
//    var artist: String
//    init(name: String, artist: String) {
//        self.artist = artist
//        super.init(name: name)
//    }
//}
//
//let library = [
//    Movie(name: "Casablanca", director: "Michael Curtiz"),
//    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
//    Movie(name: "Citizen Kane", director: "Orson Welles"),
//    Song(name: "The One And Only", artist: "Chesney Hawkes"),
//    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
//]
//// the type of "library" is inferred to be [MediaItem]
//
//// MARK: -- 检查类型 Checking Type
///*
//用类型检查操作符( is  )来检查一个实例是否属于特定子类型。
//若实例属于那个子类型，类型检查操作符返回  true  ，否则返回  false  。
//*/
//var movieCount = 0
//var songCount = 0
//
//for item in library {
//    if item is Movie {
//        ++movieCount
//    } else if item is Song {
//        ++songCount
//    }
//}
//println("Media library contains \(movieCount) movies and \(songCount) songs")
//// prints "Media library contains 2 movies and 3 songs"
//
//// MARK: -- 向下转型 Downcasting
///*
//某类型的一个常量或变量可能在幕后实际上属于一个子类。
//你可以尝试向下转到它的子类型，用类型转换操作符as
//
//当你不确定向下转型可以成功时，用类型转换的可选形式( as?  )。
//*/
//for item in library {
//    if let movie = item as? Movie {
//        println("Movie: '\(movie.name)', dir. \(movie.director)")
//    } else if let song = item as? Song {
//        println("Song: '\(song.name)', by \(song.artist)")
//    }
//}
//
//// Movie: 'Casablanca', dir. Michael Curtiz
//// Song: 'Blue Suede Shoes', by Elvis Presley
//// Movie: 'Citizen Kane', dir. Orson Welles
//// Song: 'The One And Only', by Chesney Hawkes
//// Song: 'Never Gonna Give You Up', by Rick Astley
//
//
//// MARK: -- Any & AnyObject 的类型转换
///*
//Swift为不确定类型提供了两种特殊类型别名：
//AnyObject  可以代表任何class类型的实例。
//Any  可以表示任何类型，包括方法类型（function types）。
//*/
//// MARK: ---- AnyObject类型
//let someObjects: [AnyObject] = [
//    Movie(name: "2001: A Space Odyssey", director: "Stanley Kubrick"),
//    Movie(name: "Moon", director: "Duncan Jones"),
//    Movie(name: "Alien", director: "Ridley Scott")
//]
//for object in someObjects {
//    let movie = object as! Movie
//    println("Movie: '\(movie.name)', dir. \(movie.director)")
//}
//// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick 
//// Movie: 'Moon', dir. Duncan Jones
//// Movie: 'Alien', dir. Ridley Scott
//
//for movie in someObjects as! [Movie] {
//    println("Movie: '\(movie.name)', dir. \(movie.director)")
//}
//// Movie: '2001: A Space Odyssey', dir. Stanley Kubrick 
//// Movie: 'Moon', dir. Duncan Jones
//// Movie: 'Alien', dir. Ridley Scott
//
//// MARK: ---- Any类型
//var things = [Any]()
//
//things.append(0)
//things.append(0.0)
//things.append(42)
//things.append(3.14159)
//things.append("hello")
//things.append((3.0, 5.0))
//things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
//things.append({ (name: String) -> String in "Hello, \(name)" })
//
//for thing in things {
//    switch thing {
//    case 0 as Int:
//        println("zero as an Int")
//    case 0 as Double:
//        println("zero as a Double")
//    case let someInt as Int:
//        println("an integer value of \(someInt)")
//    case let someDouble as Double where someDouble > 0:
//        println("a positive double value of \(someDouble)")
//    case is Double:
//        println("some other double value that i don't want to print")
//    case let (x, y) as (Double, Double):
//        println("an (x, y) point at \(x), \(y)")
//    case let movie as Movie:
//        println("a movie called '\(movie.name)', dir. \(movie.director)")
//    case let stringConverter as String -> String:
//        println(stringConverter("Michael"))
//    default:
//        println("something else")
//    }
//}
//
//// zero as an Int
//// zero as a Double
//// an integer value of 42
//// a positive double value of 3.14159
//// a string value of "hello"
//// an (x, y) point at 3.0, 5.0
//// a movie called 'Ghostbusters', dir. Ivan Reitman 
//// Hello, Michael
//
////}


// MARK: 嵌套类型
///*
//要在一个类型中嵌套另一个类型，将需要嵌套的类型的定义写在被嵌套类型的区域{}内，
//而且可以根据需要定义多级嵌套。
//*/
////{
//struct BlackjackCard {
//    // 嵌套定义枚举类型Suit
//    enum Suit: Character {
//        case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
//    }
//    
//    // 嵌套定义枚举类型Rank
//    enum Rank: Int {
//        case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
//        case Jack, Queen, King, Ace
//    
//        struct Values {
//            let first: Int, second: Int?
//        }
//        var values: Values {
//            switch self {
//            case .Ace:
//                return Values(first: 1, second: 11)
//            case .Jack, .Queen, .King:
//                return Values(first: 10, second: nil)
//            default:
//                return Values(first: self.rawValue, second: nil)
//            }
//        }
//    }
//
//    // BlackjackCard 的属性和方法
//    let rank: Rank, suit: Suit
//    var description: String {
//        var output = "suit is \(suit.rawValue),"
//        output += " value is \(rank.values.first)"
//        if let second = rank.values.second {
//            output += " or \(second)"
//        }
//        return output
//    }
//}
///*
//因为 BlackjackCard  是一个没有自定义构造函数的结构体，
//可以用默认的 initializer  去初始化新的常量 theAceOfSpades:
//*/
//let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
//println("theAceOfSpades: \(theAceOfSpades.description)")
//// print "theAceOfSpades: suit is ♠, value is 1 or 11"
//
//let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue
//println("heartsSymbol = \(heartsSymbol)")
//
////}



// MARK: 扩展 Extensions
/*
扩展可以添加新的计算属性，但是不能添加存储属性，
也不可以向已有属性添加属性观察器

Swift 中的扩展可以：
	添加计算型属性和计算静态属性
	定义实例方法和类型方法
	提供新的构造器
	定义下标
	定义和使用新的嵌套类型
	使一个已有类型符合某个协议
*/
// MARK: -- 扩展语法
//extension SomeType {
//    // 加到SomeType的新功能写到这里
//}
//extension SomeType: SomeProtocol, AnotherProtocol {
//    // 协议实现写到这里
//}

// MARK: -- 计算型属性 Computed Properties
////{
//extension Double {
//    var km: Double { return self * 1_000.0 }
//    var m : Double { return self}
//    var cm: Double { return self / 100.0 }
//    var mm: Double { return self / 1_000.0 }
//    var ft: Double { return self / 3.20004 }
//}
//let oneInch = 25.4.mm
//println("One inch is \(oneInch) meters")
//
//let threeFeet = 3.ft
//println("Three feet is \(threeFeet) meters")
//
//let aMarathon = 42.km + 195.m
//println("A marathon is \(aMarathon) meters long")
////}

// MARK: -- 构造器 Initializers
/*
扩展能向类中添加新的便利构造器，但是不能向类中添加新的指定构造器和解析构造器
*/
////{
//struct Size {
//    var width = 0.0, height = 0.0
//}
//struct Point {
//    var x = 0.0, y = 0.0
//}
//struct Rect {
//    var origin = Point()
//    var size = Size()
//}
//
//let defaultRect = Rect()
//let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
//                            size: Size(width: 5.0, height: 5.0))
//extension Rect {
//    init(center: Point, size: Size) {
//        let originX = center.x - (size.width/2)
//        let originY = center.y - (size.height/2)
//        self.init(origin: Point(x: originX, y: originY), size: size)
//    }
//}
//let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
////}

// MARK: -- 方法 Methods
////{
//extension Int {
//    func repetitions(task: () -> ()) {
//        for i in 0..<self {
//            task()
//        }
//    }
//}
//3.repetitions({
//    println("Hello!")
//    })
//
//// Hello!
//// Hello!
//// Hello!
//3.repetitions{
//    println("Goodbye!")
//}
//// Goodbye!
//// Goodbye!
//// Goodbye!
////}

// MARK: -- 修改实例方法 Mutating Instance Methods
/*
通过扩展添加的实例方法也可以修改该实例本身。
结构体和枚举类型中修改 self  或其属性的方法必须将该实例方法标注为 mutating  ，
正如来自原始实现的修改方法一样。
*/
////{
//extension Int {
//    mutating func square() {
//        self = self * self
//    }
//}
//var someInt = 3
//someInt.square()
//println("someInt.square = \(someInt)")
////}

// MARK: -- 下标 Subscripts
////{
//extension Int {
//    subscript(var digitIndex: Int) -> Int {
//        var decimalBase = 1
//        while digitIndex > 0 {
//            decimalBase *= 10
//            --digitIndex
//        }
//        return (self / decimalBase) % 10
//    }
//}
//println("\(746381295[0])")
//println("\(746381295[1])")
//println("\(746381295[2])")
//println("\(746381295[8])")
////}

// MARK: -- 嵌套类型 Nested Types
////{
//extension Character {
//    enum Kind {
//        case Vowel, Consonant, Other
//    }
//    var kind: Kind {
//        switch String(self).lowercaseString {
//            case "a", "e", "i", "o", "u":
//                return .Vowel
//            case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
//                "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
//                return .Consonant
//            default:
//                return .Other
//        }
//    }
//}
//
//func printLetterKinds(word: String) {
//    println("'\(word)' is made up of the following kinds of letters:")
//    for character in word {
//        switch character.kind {
//            case .Vowel:
//                print("vowel ")
//            case .Consonant:
//                print("consonant ")
//            case .Other:
//                print("other ")
//        }
//    }
//    println("\n")
//}
//
//printLetterKinds("Hello")
////}



// MARK: 协议 Protocols
/*
协议(Protocol)  用于定义完成某项任务或功能所必须的方法和属性，
协议实际上并不提供这些功能或任务的具体 实现(Implementation)  
--而只用来描述这些实现应该是什么样的。

类，结构体，枚举通过提供协议所要求的方法、属性的具体实现来 采用(adopt)  协议。
任意能够满足协议要求的类型被称为协议的 遵循者  。

协议  可以要求其 遵循者  提供特定的实例属性，实例方法，类方法，操作符或下标脚本等。
*/
// MARK: -- 协议的语法
////{
//protocol SomeProtocol {
//    //协议内容
//}
//struct SomeStructure: FirstProtocol, AnotherProtocol {
//    //结构体内容
//}
///*
//如果一个类在含有父类的同时也采用了协议，应当把父类放在所有的协议之前
//*/
//class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
//    //类的内容
//}
////}

// MARK: -- 对属性的规定
/*
协议可以规定其 遵循者 提供特定名称与类型的 实例属性(instance property)  或 类属性(type property)  ，
而不管其是 存储型属性(stored property)  还是 计算型属性(calculate property)  。
此外也可以指定属性是只读的还是可读写的。
*/
////{
///*
//协议中的属性经常被加以 var  前缀声明其为变量属性，
//在声明后加上 { set get }  来表示属性是可读写的，只读的属性则写作 { get } 
//*/
//protocol SomeProtocol {
//    var mustBeSettable: Int {get set}
//    var doesNotNeedToBeSettable: Int {get}
//}
///*
//通常在协议的定义中使用 class  前缀表示该属性为类成员；
//在枚举和结构体实现协议时中，需要使用 static  关键字作为前缀。
//*/
//protocol AnotherProtocol {
//    class var someTypeProperty: Int {get set}
//}
////}
// MARK: ---- e.g.1
////{
//protocol FullyNamed {
//    var fullName: String {get}
//}
//struct Person: FullyNamed {
//    var fullName: String
//}
//let john = Person(fullName: "John Appleseed")
//
//class Starship: FullyNamed {
//    var prefix: String?
//    var name: String
//    init(name: String, prefix: String? = nil) {
//        self.name = name
//        self.prefix = prefix
//    }
///* Starship  类把 fullName  属性实现为只读的 计算型属性  。 */
//    var fullName: String {
//        return (prefix != nil ? prefix! + " " : " ") + name
//    }
//}
//var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
//println("ncc1701=\(ncc1701.fullName)")
//// ncc1701.fullName == "USS Enterprise"
////}

// MARK: -- 对方法的规定
/*
协议  可以要求其 遵循者  实现某些指定的 实例方法  或 类方法  。
这些方法作为协议的一部分，像普通的方法一样清晰的放在协议的定义中，而不需要大括号和方法体。

协议中的方法支持 变长参数(variadic parameter)  ，不支持 参数默认值(default value)  。
*/
////{
///*
//协议中类方法的定义与类属性的定义相似，在协议定义的方法前置 class  关键字来表示。
//当在 枚举  或 结构体  实现类方法时，需要使用 static  关键字来代替。
//*/
////protocol SomeProtocol {
////    class func someTypeMethod()
////}
//
///*
//定义含有一个实例方法的的协议:
//*/
//protocol RandomNumberGenerator {
//    func random() -> Double
//}
//class LinearCongruentialGenerator: RandomNumberGenerator {
//    var lastRandom = 42.0
//    let m = 139968.0
//    let a = 3877.0
//    let c = 29573.0
//    func random() -> Double {
//        lastRandom = ((lastRandom * a + c) % m)
//        return lastRandom / m
//    }
//}
//let generator = LinearCongruentialGenerator()
//println("Here's a random number: \(generator.random())")
//// 输出 : "Here's a random number: 0.37464991998171"
//println("And another one: \(generator.random())")
//// 输出 : "And another one: 0.729023776863283"
////}

// MARK: -- 对突变方法的规定
/*
如果协议中的实例方法打算改变其 遵循者  实例的类型，
那么在协议定义时需要在方法前加 mutating  关键字，
才能使 结构体，枚举  来采用并满足协议中对方法的规定。

用 类  实现协议中的 mutating  方法时，不用写 mutating  关键字;
用 结构体  ， 枚举  实现协议中的 mutating  方法时，必须写 mutating  关键字。
*/
////{
//protocol Togglable {
//    mutating func toggle()
//}
//enum OnOffSwitch: Togglable {
//    case Off, On
//    mutating func toggle() {
//        switch self {
//        case Off:
//            self = On
//        case On:
//            self = Off
//        }
//    }
//}
//var lightSwitch = OnOffSwitch.Off
//lightSwitch.toggle()
//println("lightSwitch=\(lightSwitch.hashValue)")
////}

// MARK: -- 对构造器的规定
/*
协议可以要求它的遵循类型实现特定的构造器。
你可以像书写普通的构造器那样，在协议的定义里写下构造器的需求，
但不需要写花括号和构造器的实体
*/
////{
//protocol SomeProtocol {
//    init(someParameter: Int)
//}
///*
//必须给构造器实现标上"required"修饰符
//使用 required  修饰符可以保证：
//所有的遵循该协议的子类，同样能为构造器规定提供一个显式的实现或继承实现。
//*/
//class SomeClass: SomeProtocol {
//    required init(someParameter: Int) {
//        //构造器实现
//    }
//}
////}

/*
如果一个子类重写了父类的指定构造器，并且该构造器遵循了某个协议的规定，
那么该构造器的实现需要被同时标示 required  和 override  修饰符
*/
////{
//protocol SomeProtocol {
//    init()
//}
//class SomeSuperClass {
//    init() {
//        //协议定义
//    }
//}
//class SomeSubClass: SomeSuperClass, SomeProtocol {
//    // "required" from SomeProtocol conformance; "override" from SomeSuperClass 
//    required override init() {
//        // 构造器实现
//    }
//}
////}
/*
可以通过给协议 Protocols  中添加可失败构造器来使遵循该协议的类型必须实现该可失败构造器。
*/

// MARK: -- 协议类型
/*
尽管 协议  本身并不实现任何功能，但是 协议  可以被当做类型来使用。
使用场景:
协议类型  作为函数、方法或构造器中的参数类型或返回值类型
协议类型  作为常量、变量或属性的类型
协议类型  作为数组、字典或其他容器中的元素类型
*/
////{
//protocol RandomNumberGenerator {
//    func random() -> Double
//}
//class LinearCongruentialGenerator: RandomNumberGenerator {
//    var lastRandom = 42.0
//    let m = 139968.0
//    let a = 3877.0
//    let c = 29573.0
//    func random() -> Double {
//        lastRandom = ((lastRandom * a + c) % m)
//        return lastRandom / m
//    }
//}
//class Dice {
//    let sides: Int
//    let generator: RandomNumberGenerator
//    init(sides: Int, generator: RandomNumberGenerator) {
//        self.sides = sides
//        self.generator = generator
//    }
//    func roll() -> Int {
//        return Int(generator.random() * Double(sides)) + 1
//    }
//}
//
//var d6 = Dice(sides: 6,generator: LinearCongruentialGenerator())
//for _ in 1...5 {
//    println("Random dice roll is \(d6.roll())")
//}
////Random dice roll is 3 
////Random dice roll is 5 
////Random dice roll is 4 
////Random dice roll is 5 
////Random dice roll is 4
//
//// MARK: -- 委托(代理)模式
///*
//委托是一种设计模式,它允许 类  或 结构体  将一些需要它们负责的功能 交由(委托)  给其他的类型的实例。
//
//委托模式的实现很简单: 
//定义 协议  来 封装  那些需要被委托的 函数和方法  ， 使其 遵循者  拥有这些被委托的 函数和方法  。
//
//委托模式可以用来响应特定的动作或接收外部数据源提供的数据，
//而无需要知道外部数据源的所属类型(只要求外部数据源 遵循  某协议)。
//*/
////{
//protocol DiceGame {
//    var dice: Dice { get }
//    func play()
//}
//
//protocol DiceGameDelegate {
//    func gameDidStart(game: DiceGame)
//    func game(game: Dice, didStartNewTurnWithDiceRoll diceRoll:Int)
//    func gameDidEnd(game: DiceGame)
//}
//
//class SnakesAndLadders: DiceGame {
//    let finalSquare = 25
//    let dice = Dice(sides: 6, generator: LinearCongruentialGenerator())
//    var square = 0
//    var board: [Int]
//    init() {
//        board = [Int](count: finalSquare + 1, repeatedValue: 0)
//        board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
//        board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
//    }
//	  /*
//		delegate  并不是游戏的必备条件，
//		因此 delegate  被定义为遵循 DiceGameDelegate  协议的可选属性， 
//		delegate  使用 nil  作为初始值。
//    */
//    var delegate: DiceGameDelegate?
//    func play() {
//        square = 0
//        delegate?.gameDidStart(self)
//        gameLoop: while square != finalSquare {
//            let diceRoll = dice.roll()
//            delegate?.game(dice, didStartNewTurnWithDiceRoll: diceRoll)
////            println("square=\(square)")
//            switch square + diceRoll {
//            case finalSquare:
//                break gameLoop
//            case let newSquare where newSquare > finalSquare:
//                continue gameLoop
//            default:
//                square += diceRoll
//                square += board[square]
//            }
//        }
//        delegate?.gameDidEnd(self)
//    }
//}
//class DiceGameTracker: DiceGameDelegate {
//    var numberOfTurns = 0
//    func gameDidStart(game: DiceGame) {
//        numberOfTurns = 0
//        if game is SnakesAndLadders {
//            println("Started a new game of Snakes and Ladders")
//        }
//        println("The game is using a \(game.dice.sides)-sided dice")
//    }
//    func game(game: Dice, didStartNewTurnWithDiceRoll diceRoll: Int) {
//        ++numberOfTurns
//        println("Rolled a \(diceRoll)")
//    }
//    func gameDidEnd(game: DiceGame) {
//        println("The game lasted for \(numberOfTurns) turns")
//    }
//}
//
//let tracker = DiceGameTracker()
//let game = SnakesAndLadders()
//game.delegate = tracker
//game.play()
//// Started a new game of Snakes and Ladders
//// The game is using a 6-sided dice
//// Rolled a 3
//// Rolled a 5
//// Rolled a 4
//// Rolled a 5
//// The game lasted for 4 turns
////
//// MARK: -- 在扩展中添加协议成员
///*
//扩展  可以为已存在的类型添加 属性  ， 方法  ， 下标脚本  ， 协议  等成员。
//*/
////{
//protocol TextRepresentable {
//    func asText() -> String
//}
//extension Dice: TextRepresentable {
//    func asText() -> String {
//        return "A \(sides)-sided dice"
//    }
//}
//
//let d12 = Dice(sides: 12, generator: LinearCongruentialGenerator())
//println(d12.asText())
//// 输出 "A 12-sided dice"
//
//extension SnakesAndLadders: TextRepresentable {
//    func asText() -> String {
//        return "A game of Snakes and Ladders with \(finalSquare) squares"
//    }
//}
//println(game.asText())
//// 输出 "A game of Snakes and Ladders with 25 squares"
//
//// MARK: -- 通过扩展补充协议声明
///*
//当一个类型已经实现了协议中的所有要求，却没有声明时，可以通过 扩展  来补充协议声明
//即使满足了协议的所有要求，类型也不会自动转变，因此你必须为它做出明显的协议声明
//*/
////{
//struct Hamster {
//    var name: String
//    func asText() -> String {
//        return "A hamster named \(name)"
//    }
//}
//extension Hamster: TextRepresentable {}
//
//let simonTheHamster = Hamster(name: "Simon")
//let somethingTextRepresentable: TextRepresentable = simonTheHamster
//println(somethingTextRepresentable.asText())
//// 输出 "A hamster named Simon"
////}
//
//// MARK: -- 集合中的协议类型
///*
//协议类型可以被集合使用，表示集合中的元素均为协议类型
//*/
////{
//let things: [TextRepresentable] = [game, d12, simonTheHamster]
//for thing in things {
//    println(thing.asText())
//}
//// A game of Snakes and Ladders with 25 squares
//// A 12-sided dice
//// A hamster named Simon
////}
//
//// MARK: -- 协议的继承
////{
////protocol InheritingProtocol: SomeProtocol, AnotherProtocol {
////    //协议定义
////}
//protocol PrettyTextRepresentable: TextRepresentable {
//    func asPrettyText() -> String
//}
//extension SnakesAndLadders: PrettyTextRepresentable {
//    func asPrettyText() -> String {
//        var output = asText() + ":\n"
//        for index in 1...finalSquare {
//            switch board[index] {
//            case let ladder where ladder > 0:
//                output += "▲ "
//            case let snake where snake < 0:
//                output += "▼ "
//            default:
//                output += "○ "
//            }
//        }
//        return output
//    }
//}
//
//println(game.asPrettyText())
//// A game of Snakes and Ladders with 25 squares:
//// ○ ○ ▲ ○ ○ ▲ ○ ○ ▲ ▲ ○ ○ ○ ▼ ○ ○ ○ ○ ▼ ○ ○ ▼ ○ ▼ ○
////}
////}
////}
////}

// MARK: -- 类专属协议
/*
你可以在协议的继承列表中,通过添加“class”关键字,限制协议只能适配到类（class）类型。
（结构体或枚举不能遵循该协议）。
该“class”关键字必须是第一个出现在协议的继承列表中，其后，才是其他继承协议。
*/
////{
///*
//协议SomeClassOnlyProtocol只能被类类型适配
//如果尝试让结构体或枚举类型适配该协议，则会出现编译错误
//*/
//protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
//    // class-only protocol definition goes here
//}
////}

// MARK: -- 协议合成 Protocol Composition
/*
一个协议可由多个协议采用 protocol<SomeProtocol， AnotherProtocol>  这样的格式进行组合

协议合成  并不会生成一个新协议类型，而是将多个协议合成为一个临时的协议，超出范围后立即失效。
*/
////{
//protocol Named {
//    var name: String { get }
//}
//protocol Aged {
//    var age: Int { get }
//}
//struct Person: Named, Aged {
//    var name: String
//    var age: Int
//}
//func wishHappyBirthday(celebrator: protocol<Named, Aged>) {
//    println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!")
//}
//
//let birthdayPerson = Person(name: "Malcolm", age: 21)
//wishHappyBirthday(birthdayPerson)
////}

// MARK: -- 检验协议的一致性
/*
使用 is  和 as  操作符来检查协议的一致性或转化协议类型。
is   操作符用来检查实例是否 遵循  了某个 协议  。
as?  返回一个可选值，当实例 遵循  协议时，返回该协议类型;否则返回 nil
as   用以强制向下转型。
*/
////{
//@objc protocol HasArea {
//    var area: Double { get }
//}
//class Circle: HasArea {
//    let pi = 3.1415927
//    var radius: Double
//    @objc var area: Double { return pi * radius * radius }
//    init(radius: Double) { self.radius = radius }
//}
//class Country: HasArea {
//    @objc var area: Double
//    init(area: Double) { self.area = area }
//}
//class Animal {
//    var legs: Int
//    init(legs: Int) { self.legs = legs }
//}
//
//let objects: [AnyObject] = [
//    Circle(radius: 2.0),
//    Country(area: 243_610),
//    Animal(legs: 4)
//]
//for object in objects {
//    if let objectWithArea = object as? HasArea {
//        println("Area is \(objectWithArea.area)")
////    if object is HasArea
////        println("Area is \(object.area)")
//    } else {
//        println("Something that doesn't have an area")
//    }
//}
//// Area is 12.5663708
//// Area is 243610.0
//// Something that doesn't have an area
////}

// MARK: -- 对可选协议的规定
/*
可选协议含有可选成员，其 遵循者  可以选择是否实现这些成员。
在协议中使用 @optional  关键字作为前缀来定义可选成员。

可选协议在调用时使用 可选链

可选协议只能在含有 @objc  前缀的协议中生效。且 @objc  的协议只能被 类  遵循

@objc  用来表示协议是可选的，也可以用来表示暴露给 Objective-C  的代码，
此外， @objc  型协议只对 类  有效，因此只能在 类  中检查协议的一致性。
*/
////{
//@objc protocol CounterDataSource {
//    optional func incrementForCount(count: Int) -> Int
//    optional var fixedIncrement: Int { get }
//}
//@objc class Counter {
//    var count = 0
//    var dataSource: CounterDataSource?
//    func increment() {
//        if let amount = dataSource?.incrementForCount?(count) {
////            println("incrementForCount enabled")
//            count += amount
//        } else if let amount = dataSource?.fixedIncrement {
////            println("fixedIncrement enabled")
//            count += amount
//        }
//    }
//}
//class ThreeSource: CounterDataSource {
//    @objc let fixedIncrement = 3
//}
//
//var counter = Counter()
//counter.dataSource = ThreeSource()
//for _ in 1...4 {
//    counter.increment()
//    println(counter.count)
//}
//
//// 3 
//// 6 
//// 9 
//// 12
//
//class TowardsZeroSource: CounterDataSource {
//    @objc func incrementForCount(count: Int) -> Int {
//        if count == 0 {
//            return 0
//        } else if count < 0 {
//             return 1
//        } else {
//            return -1
//        }
//    }
//}
//
//counter.count = -4
//counter.dataSource = TowardsZeroSource()
//for _ in 1...5 {
//    counter.increment()
//    println(counter.count)
//}
//
//// -3 
//// -2
//// -1
//// 0
//// 0
////}



// MARK: 泛型
/*
泛型代码可以让你写出根据自我需求定义、适用于任何类型的，灵活且可重用的函数和类型。
它的可以让你避免重复的代码，用一种清晰和抽象的方式来表达代码的意图。
*/
////{
///*
//这个函数的泛型版本使用了占位类型名字（通常此情况下用字母 T  来表示）
//来代替实际类型名（如 Int  、 String  或 Double  ）。
//
//占位类型名字（T）是用尖括号括起来的（ <T>  ）。
//这个尖括号告诉 Swift那个 T  是 swapTwoValues  函数所定义的一个类型。
//因为 T  是一个占位命名类型，Swift 不会去查找命名为T的实际类型。
//*/
//func swapTwoValues<T>(inout a: T, inout b: T) {
//	let temporaryA = a
//	a = b
//	b = temporaryA
//}
//
//var someInt = 3
//var anotherInt = 107
//swapTwoValues(&someInt, &anotherInt)
//println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
//// 输出 "someInt is now 107, and anotherInt is now 3"
//
//var someString = "hello"
//var anotherString = "world"
//swapTwoValues(&someString, &anotherString)
//// someString is now "world", and anotherString is now "hello"
////}

// MARK: -- 类型参数
/*
类型参数指定并命名为一个占位类型，并且紧随在函数名后面，使用一对尖括号括起来（如 <T>  ）。

一旦一个类型参数被指定，那么其可以被使用来定义一个函数的参数类型
（如 swapTwoValues  函数中的参数 a  和 b  ），或作为一个函数返回类型，或用作函数主体中的注释类型。

你可支持多个类型参数，命名在尖括号中，用逗号分开。

请始终使用大写字母开头的驼峰式命名法（例如 T  和 KeyType  ）来给类型参数命名，
以表明它们是类型的占位符，而非类型值。
*/

// MARK: -- 泛型类型
////{
//struct IntStack {
//	var items = [Int]()
//	/*
//	这里由于是要修改结构体里的数组,故使用异变方法
//	*/
//	mutating func push(item: Int) {
//		items.append(item)
//	}
//	mutating func pop() -> Int {
//		return items.removeLast()
//	}
//}
//
//// 泛型版本
//struct Stack<T> {
//	var items = [T]()
//	/*
//	这里由于是要修改结构体里的数组,故使用异变方法
//	*/
//	mutating func push(item: T) {
//		items.append(item)
//	}
//	mutating func pop() -> T {
//		return items.removeLast()
//	}
//}
//
//var stackOfStrings = Stack<String>()
//stackOfStrings.push("uno")
//stackOfStrings.push("dos")
//stackOfStrings.push("tres")
//stackOfStrings.push("cuatro")
//// 现在栈已经有4个string了
//let fromTheTop = stackOfStrings.pop()
//// fromTheTop is equal to "cuatro", and the stack now contains 3 strings
////}

// MARK: -- 类型约束
/*
类型约束指定了一个必须继承自指定类的类型参数，或者遵循一个特定的协议或协议构成。
*/
// MARK: ---- 类型约束语法
//{
/*
 T  必须是 SomeClass  子类的类型约束
 U  必须遵循 SomeProtocol  协议的类型约束

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
	// function body goes here
}
*/
//}
// MARK: ---- 类型约束行为
////{
//func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
//	for (index, value) in enumerate(array) {
//		if value == valueToFind {
//			return index
//		}
//	}
//	return nil
//}
//
//let doubleIndex = findIndex([3.14159, 0.1, 0.25], 9.3)
//// doubleIndex is an optional Int with no value, because 9.3 is not in the array
//let stringIndex = findIndex(["Mike", "Malcolm", "Andrea"], "Andrea")
//// stringIndex is an optional Int containing a value of 2
////}

// MARK: -- 关联类型 Associated Types
/*
一个关联类型作为协议的一部分，给定了类型的一个占位名（或别名）。
作用于关联类型上实际类型在协议被实现前是不需要指定的。
关联类型被指定为 typealias  关键字。
*/
// MARK: ---- 关联类型行为
////{
//protocol Container {
//	/*
//	Container  协议定义了三个任何容器必须支持的兼容要求：
//	必须可以通过 append  方法添加一个新item到容器里；
//	必须可以通过使用 count  属性获取容器里items的数量，并返回一个 Int  值；
//	必须可以通过容器的 Int  索引值下标可以检索到每一个item。
//
//	这个协议没有指定容器里item是如何存储的或何种类型是允许的。
//	这个协议只指定任何遵循 Container  类型所必须支持的三个功能点。
//	一个遵循的类型在满足这三个条件的情况下也可以提供其他额外的功能。
//
//	任何遵循 Container  协议的类型必须指定存储在其里面的值类型，
//	必须保证只有正确类型的items可以加进容器里，
//	必须明确可以通过其下标返回item类型。
//	*/
//	typealias ItemType
//	mutating func append(item: ItemType)
//	var count: Int { get }
//	subscript(i: Int) -> ItemType {	get	}
//}
//
//struct IntStack: Container {
//	// IntStack的原始实现
//	var items = [Int]()
//	mutating func push(item: Int) {
//		items.append(item)
//	}
//	mutating func pop() -> Int {
//		return items.removeLast()
//	}
//	// 遵循Container协议的实现
//	// typealias ItemType = Int //由于swift的类型推导,这行声明可以省略
//	mutating func append(item: Int) {
//		self.push(item)
//	}
//	var count: Int {
//		return items.count
//	}
//	subscript(i: Int) -> Int {
//		return items[i]
//	}
//}
//
//struct Stack<T>: Container {
//	// 原始实现
//	var items = [T]()
//	mutating func push(item: T) {
//		items.append(item)
//	}
//	mutating func pop() -> T {
//		return items.removeLast()
//	}
//	// 遵循Container协议的实现
//	mutating func append(item: T) {
//		self.push(item)
//	}
//	var count: Int {
//		return items.count
//	}
//	subscript(i: Int) -> T {
//		return items[i]
//	}
//}
//
//// MARK: ---- 扩展一个存在的类型为一指定关联类型
////{
///*
//Swift的 Array  已经提供 append  方法，一个 count  属性和通过下标来查找一个自己的元素。
//这三个功能都达到 Container  协议的要求。
//也就意味着你可以扩展 Array  去遵循 Container  协议，只要通过简单声明 Array  适用于该协议而已
//
//定义了这个扩展后，你可以将任何 Array  当作 Container  来使用。
//*/
//extension Array: Container {}
////}
//
//// MARK: ---- Where 语句
////{
//func allItemsMatch<
//    C1: Container, C2: Container
//    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
//    (someContainer: C1, anotherContainer: C2) -> Bool {
//        // 检查两个Container的元素个数是否相同
//        if someContainer.count != anotherContainer.count {
//            return false
//        }
//        
//        // 检查两个Container相应位置的元素彼此是否相等
//        for i in 0..<someContainer.count {
//            if someContainer[i] != anotherContainer[i] {
//                return false
//            }
//        }
//        
//        // 如果所有元素检查都相同则返回true
//        return true
//}
//
//var stackOfStrings = Stack<String>()
//stackOfStrings.push("uno")
//stackOfStrings.push("dos")
//stackOfStrings.push("tres")
//
//var arrayOfStrings = ["uno", "dos", "tres"]
//
//if allItemsMatch(stackOfStrings, arrayOfStrings) {
//    println("All items match.")
//} else {
//    println("Not all items match.")
//}
//// 输出 "All items match."
////}
////}




// MARK: 访问控制
/*
Public  ：可以访问自己模块或应用中源文件里的任何实体，别人也可以访问引入该模块中源文件里的所有实体。
通常情况下，某个接口或 Framework  是可以被任何人使用时，你可以将其设置为 public  级别。
Internal  ：可以访问自己模块或应用中源文件里的任何实体，但是别人不能访问该模块中源文件里的实体。
通常情况下，某个接口或 Framework  作为内部结构使用时，你可以将其设置为 internal  级别。
Private  ：只能在当前源文件中使用的实体，称为私有实体。
使用 private  级别，可以用作隐藏某些功能的实现细节。

一个 public  访问级别的变量，不能将它的类型定义为 internal  和 private  的类型。
函数的访问级别不能高于它的参数、返回类型的访问级别。

代码中的所有实体，如果你不明确的定义其访问级别，那么它们默认为 internal  级别。

当你开发 Framework  时，就需要把一些实体定义为 public  级别，以便其他人导入该 Framework  后可以正常使用其功能。
这些被你定义为 public  的实体，就是这个 Framework  的API。

一个 public  类的所有成员的访问级别默认为 internal  级别，而不是 public  级别。
如果你想将某个成员申明为 public  级别，那么你必须使用修饰符明确的申明该成员。

public class SomePublicClass { // 显示的 public 类
	public var somePublicProperty = 0 // 显示的 public 类成员
	var someInternalProperty = 0 // 隐式的 internal 类成员
	private func somePrivateMethod() {} // 显示的 private 类成员
}
class SomeInternalClass { // 隐式的 internal 类
	var someInternalProperty = 0 // 隐式的 internal 类成员
	private func somePrivateMethod() {} // 显示的 private 类成员
}
private class SomePrivateClass { // 显示的 private 类
	var somePrivateProperty = 0 // 隐式的 private 类成员
	func somePrivateMethod() {} // 隐式的 private 类成员
}
*/


// MARK: 高级运算符

// MARK: -- 溢出运算符
/*
溢出加法  &+
溢出减法  &-
溢出乘法  &*
溢出除法  &/
溢出求余  &%
*/

// MARK: -- 运算符函数
/*
默认的赋值符(=)是不可重载的。只有组合赋值符可以重载。
三目条件运算符  a？b：c  也是不可重载。
*/
////{
//struct Vector2D {
//	var x = 0.0, y = 0.0
//}
//func + (left: Vector2D, right: Vector2D) -> Vector2D {
//	return Vector2D(x: left.x + right.x, y: left.y + right.y)
//}
//let vector = Vector2D(x: 3.0, y: 1.0)
//let anotherVector = Vector2D(x: 2.0, y: 4.0)
//let combinedVector = vector + anotherVector
//// combinedVector 是一个新的Vector2D, 值为 (5.0, 5.0)
//
//// MARK: ---- 前置和后置运算符
//prefix func - (vector: Vector2D) -> Vector2D {
//	return Vector2D(x: -vector.x, y: -vector.y)
//}
//let positive = Vector2D(x: 3.0, y: 4.0)
//let negative = -positive
//// negative 为 (-3.0, -4.0)
//let alsoPositive = -negative
//// alsoPositive 为 (3.0, 4.0)
//
//// MARK: ---- 组合赋值运算符
//func += (inout left: Vector2D, right: Vector2D) {
//	left = left + right
//}
//var original = Vector2D(x: 1.0, y: 2.0)
//let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
//original += vectorToAdd
//// original 现在为 (4.0, 6.0)
//
//prefix func ++ (inout vector: Vector2D) -> Vector2D {
//	vector += Vector2D(x: 1.0, y: 1.0)
//	return vector
//}
//var toIncrement = Vector2D(x: 3.0, y: 4.0)
//let afterIncrement = ++toIncrement
//// toIncrement 现在是 (4.0, 5.0)
//// afterIncrement 现在也是 (4.0, 5.0)
//
//// MARK: ---- 比较运算符
//func == (left: Vector2D, right: Vector2D) -> Bool {
//	return (left.x == right.x) && (left.y == right.y)
//}
//func != (left: Vector2D, right: Vector2D) -> Bool {
//	return !(left == right)
//}
//let twoThree = Vector2D(x: 2.0, y: 3.0)
//let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
//if twoThree == anotherTwoThree {
//	println("这两个向量是相等的.")
//}
//// prints "这两个向量是相等的."
//
//// MARK: ---- 自定义运算符
//prefix operator +++ {}
//prefix func +++ (inout vector: Vector2D) -> Vector2D {
//	vector += vector
//	return vector
//}
//var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
//let afterDoubling = +++toBeDoubled
//// toBeDoubled 现在是 (2.0, 8.0)
//// afterDoubling 现在也是 (2.0, 8.0)
//
//// MARK: ---- 自定义运算符优先级 Precedence and Associativity for Custom Infix Operators
//infix operator +- { associativity left precedence 140 }
//func +- (left: Vector2D, right: Vector2D) -> Vector2D {
//    return Vector2D(x: left.x + right.x, y: left.y - right.y)
//}
//let firstVector = Vector2D(x: 1.0, y: 2.0)
//let secondVector = Vector2D(x: 3.0, y: 4.0)
//let plusMinusVector = firstVector +- secondVector
////}



// MARK: 元类型
/*
元类型是指所有类型的类型，包括类、结构体、枚举和协议。
类、结构体或枚举类型的元类型是相应的类型名紧跟 .Type  。

你可以使用后缀 self  表达式来获取类型。
比如， SomeClass.self  返回 SomeClass  本身，而不是 SomeClass  的一个实例。
同样， SomeProtocol.self  返回 SomeProtocol  本身，而不是运行时适配 SomeProtocol  的某个类型的实例。

还可以对类型的实例使用 dynamicType  表达式来获取该实例在运行阶段的类型
*/
////{
//class SomeBaseClass {
//	class func printClassName() {
//		println("SomeBaseClass")
//	}
//}
//class SomeSubClass: SomeBaseClass {
//	override class func printClassName() {
//		println("SomeSubClass")
//	}
//}
//let someInstance: SomeBaseClass = SomeSubClass()
//// someInstance is of type SomeBaseClass at compile time, but
//// someInstance is of type SomeSubClass at runtime
//someInstance.dynamicType.printClassName()
//// prints "SomeSubClass
////}


// MARK: self表达式
/*
self
self.member name
self[subscript index]
self(initializer arguments)
self.init(initializer arguments)
*/
//{
/*
在mutating 方法中， 你可以使用self 对 该instance进行赋值。
*/
//struct Point {
//	var x = 0.0, y = 0.0
//    mutating func moveByX(deltaX: Double, y deltaY: Double) {
//		self = Point(x: x + deltaX, y: y + deltaY)
//	}
//}
//}